Как парсить инстаграм на python
Перейти к содержимому

Как парсить инстаграм на python

  • автор:

Парсинг instagram

Как я могу получить все ссылки на публикации аккаунта в инстаграме? Пробовал через bs4, requests, selenium, все это с headers’ами В html одно и тоже и нет нужного, как будто js блокирует или что-то типа того. Подскажите в какую сторону думать? Такая проблема именно с сайтом инстаграмма.

Отслеживать
Clark Devlin
задан 28 янв 2020 в 1:15
Clark Devlin Clark Devlin
1,434 1 1 золотой знак 14 14 серебряных знаков 33 33 бронзовых знака

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Есть прекрасный запрос, который возвращает кучу данных о пользователе(включая информацию о последних 15 постах). А там уже можно будет покопаться с bs4 и работой со словарями.

'https://instagram.com/zuck/?__a=1' 

Отслеживать
ответ дан 4 июн 2020 в 11:15
11 1 1 бронзовый знак

Попробуйте использовать instagram api. Есть несколько модулей для пайтона. Так же вот, что можно найти в документации про получение постов

Так же, возможно, стоит обратить внимание на этот репозиторий

Отслеживать
ответ дан 28 янв 2020 в 1:27
744 6 6 серебряных знаков 20 20 бронзовых знаков

На сколько я знаю, апи у инстаграма ограниченное, пока они тебе его не одобрят. А в ограниченной версии можно было только 20 последних постов получить, по крайней мере раньше. Да, и посты мне нужны не со своего аккаунта.

28 янв 2020 в 1:28

@ClarkDevlin так как в коде страницы нет всех постов, думаю, единственных выход это имитация бразуера через requests или selenuim, как удобно тебе

28 янв 2020 в 1:31

я понимаю, но когда я получаю html файл с помощью этих библиотек там совершенно не то, что в браузере. В коде посты есть, если через браузер смотреть, во вложенных дивах.

Как выполнить веб-скрапинг данных из социальных сетей — актуальное руководство 2024 года

Из этого руководства вы узнаете, как извлекать нужные данные из социальных сетей с помощью Python — мощного инструмента для веб-скрапинга.

4 min read
Sooter Saalu

Cоциальные сети, поимо всего прочего, предлагают огромное количество информации, которую можно использовать для исследования рынка, анализа конкурентов, управления репутацией и обслуживания клиентов. Получая доступ к этим данным с помощью веб-скрапинга, ваш бизнес сможет принимать обоснованные решения, улучшать репутацию своего бренда и получать конкурентное преимущество на рынке.

С помощью веб-скрапинга вы можете эффективно перемещаться по веб-страницам, выбирать конкретные данные и извлекать их в структурированном формате, например, в виде файла CSV или JSON.

Из этого руководства вы узнаете, как с помощью Python извлечь нужные данные из социальных сетей. Python широко известен как мощный инструмент для веб-скрапинга благодаря обширному набору библиотек, которые существенно облегчают парсинг, извлечение и сопоставление различных типов данных.

Скрапинг социальных сетей с помощью Python

Прежде чем приступить к этому руководству, вам понадобится следующее:

  • Python: язык программирования, используемый для данного руководства.
  • pip: менеджер пакетов для Python. Он полезен для получения нужных библиотек.
  • Beautiful Soup: полезный пакет Python для парсинга и извлечения данных из файлов HTML и XML. Информацию о том, как его загрузить, можно найти в этой документации.
  • Selenium: фреймворк для выполнения операций в браузере, который позволяет рендерить и парсить динамические сайты и сайты с поддержкой JavaScript. Более подробную информацию о том, как установить Selenium, вы можете найти в этой официальной документации.

Благодаря этому руководству вы научитесь настраивать собственную среду Python с помощью установки нужных пакетов. После этого останется запустить написанный на Python скрипт для веб-скрапинга данных из интернета. Однако многие социальные сети, например, Facebook и Instagram часто внедряют специальные блокираторы, предназначенные ботов-скраперов: определенные условия для входа в учетную запись, сокрытие полезных данных за кнопками и динамическим контентом или использование JavaScript для отображения данных. Вы будете использовать Selenium, чтобы обойти все эти меры и ограничить веб-скрапинг публичными страницами, чтобы иключить необходимость в учетных данных для входа.

Весь код для этого руководства доступен в этом репозитории GitHub.

Веб-скрапинг Facebook с помощью Python

Первый шаг при веб-скрапинге — внимательное изучение страницы, которую необходимо спарсить. Прежде всего, необходимо определиться, какие данные вам нужны и какие селекторы предоставят вам к ним доступ.

Например, просматривая публичный профиль Тома Круза в Facebook, вы найдете информацию о нем, ссылки на другие его страницы, посты, которые он публикует, рекламируя свои фильмы, и различные медиа. Вся информация, которую вы видите на этой странице, может быть извлечена с помощью веб-скрапинга.

Для того чтобы спарсить содержимое постов Тома Круза, необходимо проверить страницу на наличие селекторов, которые используются в интересующих вас постах:

Как только вы найдете селекторы, которые выделяют нужные вам данные, можно приступать к написанию кода для веб-скрапинга. Откройте файл Python ( .py ) и импортируйте в него пакеты, которые планируете использовать: Selenium для доступа к содержимому HTML-страницы, Beautiful Soup для парсинга и извлечения конкретных данных и pandas для структурирования и очистки конечного набора данных:

from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup import pandas as pd

Затем определитесь со страницей, данные которой вам нужны, и добавьте опции в Selenium, чтобы имитировать реального пользователя и избежать блокировки вашего краулера:

 # Define the URL you want to scrape url = 'https://www.facebook.com/officialtomcruise/' # Define the options for the Chrome webdriver options = Options() options.add_argument('--headless') options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3') # Create a new instance of the Chrome webdriver with the defined options driver = webdriver.Chrome(options=options) # Load the Facebook page in the webdriver driver.get(url) 

На данном этапе вы извлекли всю искомую информацию со страницы, однако она пока не представлена в удобочитаемом формате. Чтобы исправить это, воспользуйтесь Beautiful Soup для извлечения нужного текста с помощью выделенного ранее селектора:

# Extract the HTML content of the page using BeautifulSoup html_content = driver.page_source soup = BeautifulSoup(html_content, 'html.parser') posts = soup.find_all('div', class_='x1l90r2v') # Extract the text content of each post post_content = [post.text for post in posts] # Save the scraped data in a CSV file data = pd.DataFrame() data.to_csv('facebook_posts.csv', index=False) # Print the scraped data print(data) # Close the webdriver driver.quit() 

Как только вы выделили необходимые данные, можно структурировать их в виде DataFrame (или любой другой подходящей вам структуры). DataFrame — широко используемая структура данных, поскольку она предлагает удобное табличное представление данных:

Веб-скрапинг Twitter с помощью Python

Теперь, когда вы выполнили веб-скрапинг страницы на Facebook, выполните то же самое и для Twitter.

Изучите страницу Тома Круза в Twitter и выделите селектор, который можно использовать для получения доступа к нужным вам данным:

Например, в данном примере вы будете парсить текст из всех его твитов. В коде сайта есть атрибут data-testid = tweetText , который можно использовать для эффективного извлечения.

Важно учитывать особенности поведения сайтов, которые вы планируете использовать для веб-скрапинга. Например, Twitter применяет JavaScript для реализации функции бесконечной прокрутки. Это означает, что по мере прокрутки страницы вниз появляется все больше данных, и если вы попытаетесь извлечь содержимое сразу после загрузки страницы, рискуете упустить львиную долю доступных данных или получить ошибку.

Чтобы нивелировать эту проблему, можно либо настроить бота на ожидание определенного количества времени перед тем, как выполнить веб-скрапинг, либо обеспечить достаточную прокрутку страницы для получения всех необходимых данных.

Снова создайте файл Python и используйте следующий код для поиска нужного содержимого:

from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup import pandas as pd from selenium.webdriver.support import expected_conditions from selenium.webdriver.support.ui import WebDriverWait from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.by import By import time # Define the URL you want to scrape url = 'https://twitter.com/TomCruise' # Define the options for the Chrome webdriver to mimic a real page options = Options() options.add_argument('--headless') options.add_argument("--incognito") options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3') options.add_argument("--enable-javascript") # Create a new instance of the Chrome webdriver with the defined options driver = webdriver.Chrome(options=options) # Load the Twitter page in the webdriver driver.get(url) # Wait for tweets to populate the page try: WebDriverWait(driver, 60).until(expected_conditions.presence_of_element_located( (By.CSS_SELECTOR, '[data-testid="tweet"]'))) except WebDriverException: print("Something happened. No tweets loaded") # scroll a bit for more tweets to appear driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(10) # Extract the HTML content of the page using BeautifulSoup html_content = driver.page_source soup = BeautifulSoup(html_content, 'html.parser') posts = soup.find_all(attrs=) # Extract the text content of each post post_content = [post.text for post in posts] # Save the scraped data in a CSV file data = pd.DataFrame() data.to_csv('twitter_posts.csv', index=False) # Print the scraped data print(data) # Close the webdriver driver.quit()

Веб-скрапинг Instagram с помощью Python

И, наконец, посмотрите, как вы можете выполнить веб-скрапинг в случае с Instagram.

Если вы не вошли в систему, страница Тома Круза в Instagram представляется как медиагалерея, где есть только фотографии и видео. Однако внимательное изучение страницы показывает, что альтернативный текст медиафайлов в большинстве случаев содержит также содержание поста. Это означает, что вы можете считывать URL-адреса медиафайлов и их alt-описания прямо с этой страницы:

Для этого вам требуется только найти селекторы для ваших данных и структурировать DataFrame для сбора информации:

from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup import pandas as pd # Define the URL you want to scrape url = 'https://www.instagram.com/tomcruise' # Define the options for the Chrome webdriver options = Options() options.add_argument('--headless') options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3') # Create a new instance of the Chrome webdriver with the defined options driver = webdriver.Chrome(options=options) # Load the Instagram page in the webdriver driver.get(url) # Extract the HTML content of the page using BeautifulSoup html_content = driver.page_source soup = BeautifulSoup(html_content, 'html.parser') # Collect instagram links links = soup.find_all('a', href= True) # Limit the collected links to posts data posts = [] for i in links : if '/p/' in i: posts.append(i) # Save the scraped data in a CSV file data = pd.DataFrame() data.to_csv('instagram_posts.csv', index=False) # Print the scraped data print(data) # Close the webdriver driver.quit() 

Веб-скрапинг социальных сетей с помощью Bright Data

Веб-скрапинг может быть трудоемким и утомительным процессом, но не обязательно.

Bright Data — веб-платформа, которая позволяет компаниям легко получать доступ к огромным объемам общедоступных структурированных данных из сети. Например, в виде наборов данных из социальных сетей. Они содержат массу полезной информации, включая профили пользователей, а также их сообщения и комментарии, к которым можно получить доступ без необходимости самостоятельного сбора данных.

Кроме того, если вы хотите получить данные из других источников, вам могут помочь такие инструменты от Bright Data, как Web Scraper IDE и Web Unlocker. Они поставляются с предварительно созданными шаблонами для сокращения объема кода, который вам понадобится написать, и имеют встроенные прокси, которые помогут получить доступ к заблокированному региону или обойти каптчу.

Использование инструментов Bright Data для веб-скрапинга данных из социальных сетей представляет собой куда более эффективный и надежный способ, чем самостоятельный парсинг. Более того, Bright Data предоставляет обширную прокси-сеть, которая позволяет обходить ограничения по скорости и предотвращать блокировку IP-адресов при извлечении данных из социальных сетей.

Заключение

В этой статье вы ознакомились с основами веб-скрапинга и получили представление о том, как использовать Python для парсинга данных из таких социальных сетей, как Facebook, Twitter и Instagram. Мы также рассмотрели важные факторы, которые необходимо учитывать при ручном парсинге социальных сетей, и изучили инструменты Bright Data для быстрого и удобного и веб-скрапинга социальных сетей без каких-либо ограничений.

С помощью веб-скрапинга можно собирать данные из социальных сетей для маркетинговых исследований, анализа актуальных трендов и выявления топовых инфлюэнсеров. Однако веб-скрапинг важно использовать этично, соблюдая правила сайтов и социальных сетей, которые вы парсите. Убедитесь, что собираемые вами данные являются общедоступными и не нарушают законы о конфиденциальности. Инструменты, предлагаемые компанией Bright Data, особенно полезны, поскольку помогут вам сориентироваться в юридических и этических вопросах, связанных со сбором информации.

Вытаскиваем данные из Instagram

Давайте разберемся, как с помощью достаточно простого кода на python можно вытащить из инстаграмма разные данные, находящиеся в открытом доступе.

Intro

При фазовом переходе из состояния Employed в Self-Employed я погрузился в собственные проекты, которые давно хотел сделать. После парочки телеграм ботов с e-acquiring я решил попытать счастья с Instagram. Как человеку, прежде работавшему только с готовыми и подчищенными данными, мне было интересно познакомиться с процессом добычи данных поближе.

Если вам лень читать всё, то вот демонстрационный бот в Телеграм, который может вытаскивать некоторые данные из Instargam.

На данный момент бот может обрабатывать несколько запросов

  • Случайный выбор подписчика / подписчиков аккаунта
  • Случайный выбор пользователя / пользователей, поставивших лайк под постом
  • Случайный выбор комментатора / комментаторов, оставивших комментарий под постом
  • Общие подписчики для двух пользователей
  • user-info JSON (информация о пользователе Instagram в том виде в котором она хранится на серверах)
  • media-info JSON (информация о публицации в Instagram в том виде, в котором она хранится на серверах)

P.S. Надеюсь, он не упадет под натиском запросов

P.P.S И надеюсь, что профиль в инсте, через который проводятся запросы не заблочат

Inspiration

Во многом меня вдохновила статья, где анализируются самые популярные геотеги Москвы, и телеграм канал её автора. Мне стало интересно, а как вообще вытаскиваются данные из социальных сетей.

Какое API выбрать?

Начнем с того, какие библиотеки использовать. Так как я пишу на питоне, то библиотеки выбирал под него.

У Facebook есть официальное API для взаимодействия с Instagram. Это API Graph и API Instagram Basic Display. Процесс его настройки и использования показался мне чрезмерно сложным, поэтому я решил поискать решение попроще.

Из неофициальных API есть сравнительно популярный InstaPy (12k GitHub), работающий на базе Selenium. Мне такой фреймворк показался громоздким.

После нескольких часов поисков мой выбор пал на достаточно удобную библиотеку instabot, сама библиотека, документация.

Прежде чем мы начнем разбираться с кодом, стоит сделать пару замечаний. Сразу оговорюсь, что я достаточно скептически отношусь к использованию таких фреймворков для автоматизации активности (лайки, комментарии, подписки) с целью увеличения аудитории.

Инстраграм не особо хорошо относится к использованию такого рода библиотек в целях раскрутки, да и в целом, к «нечеловеческой» активности относится негативно. Поэтому не рекомендую использовать их на своём основном аккаунте. Не знаю, какая вероятность того, что вас могут заблокировать, но она явно отлична от нуля.

Мой основной интерес был в том, чтобы поиграться с данными.

Что можно сделать?

В рамках данной статьи я расскажу о том, как можно получать следующую информацию:

  • Подписки и подписчики определенного аккаунта
  • Пользователи поставившие лайк / оставившие комментарий
  • Посты определенного пользователя
  • Информация о пользователе
  • Загрузка изображений из Instagram

Гораздо интереснее рассматривать такой процесс сбора информации не как изолированную задачу, а как задачу прикладную. Поэтому для каждого пункта я нашёл некоторые реальные задачи и показал, как их можно решить.

Список подписчиков

Представим ситуацию, что вы юный блоггер, и для расширения аудитории решили провести розыгрыш. Новый год, тем более скоро, так что пример актуальный. Допустим, что основной критерий розыгрыша — быть подписанным на вас.

Таким образом мы можем сформулировать задачу — как случайным образом выбрать одного или несколько подписчиков, чтобы вручить им подарки.

Давайте посмотрим, как это можно сделать. Для начала необходимо авторизоваться. К слову, чтобы не подвергать риску свой основной аккаунт я создал новый и все запросы проводил через него.

from instabot import Bot bot = Bot() bot.login(username = INST_USERNAME, password = INST_PASSWORD)

После того, как мы авторизовались — мы можем получить список подписчиков и список подписок для любого пользователя с открытым аккаунтом. Осуществляется это следующим образом.

user_followers = bot.get_user_followers(username) # Список подписчиков user_following = bot.get_user_following(username) # Список подписок

Стоит заметить, что в данном случае мы увидим что-то вида

['1537613519', '7174630295', '5480786626', . , '6230009450', '4294562266', '27518898596']

Это user_id пользователей. Для того чтобы получить юзернеймы пользователей нужно сделать следующее:

user_id = user_followers[i] username = bot.get_username_from_user_id(user_id)

Однако стоит иметь ввиду, что запрос get_username_from_user_id работает не мгновенно и внутри программы лучше работать с user_id а резолвить его в юзернейм только при необходимости.

Выбрать случайным образом несколько подписчиков username можно, например, вот так

user_followers = bot.get_user_followers(username) amount = len(user_followers) winners = np.random.choice(amount, N, replace=False) winners_usernames = [bot.get_username_from_user_id(users_followers[i]) for i in winners]

Учитывая, что блоггеры любят проводить коллективные розыгрыши — можно получить списки подписчиков для нескольких аккаунтов и уже среди множества пользователей, подписанных на все необходимые профили, выбирать победителей.

Список людей, поставивших лайк

Продолжая эксплуатировать блогерскую тематику, представим, что вы проводите розыгрыш не только среди пользователей, подписанных на вас, но и оставивших лайк под вашим постом. Как получить список пользователей в таком случае?

Для начала нужно получить media_pk из ссылки на ваш пост:

media_link = 'https://www.instagram.com/p/CJQRFj4Jq1G/?utm_source=ig_web_copy_link' media_pk = bot.get_media_id_from_link(media_link)

Тогда для списка людей, поставивших лайк:

users_liked = bot.get_media_likers(media_pk)

Список людей, оставивших комментарий:

users_commented = bot.get_media_commenters(media_pk)

Также можно получить список комментариев под постом

comments = bot.get_media_comments(media_pk) # 20 last comments all_comments = bot.get_media_comments_all(media_pk) #all comments

Дальше с этими списками можно работать точно также, как и в предыдущем пункте. Например, можно выбирать победителей среди тех пользователей, которые подписаны на вас и которые оставили лайк и комментарий под последними N публикациями.

Посты пользователя

Давайте перейдём к более интересным вещам и посмотрим, какую информацию о наших постах предоставляет Instagram. В библиотеке есть методы, позволяющие получить информацию о постах пользователя.

Например вот так можно получить идентификаторы последних 20 постов пользователя:

twony_last_medias = bot.get_user_medias(username, filtration = None)

Параметр filtration отвечает за фильтрацию постов. Он выбрасывает посты, количество лайков которых либо меньше bot.min_likes_to_like , либо больше bot.max_likes_to_like Эти параметры можно настроить и поставить filtration = True .

В данном случае twony_last_medias будет иметь вид:

twony_last_medias = [ '2442850452985735104_381142195', . , '2242166462844436702_381142195'] 

Где первая часть, до _ — это идентификатор поста, а вторая часть — user_id , то есть media_id = _

Посмотрим, какую информацию о постах нам может дать Instagram:

media_id = twony_last_medias[i] media_info = bot.get_media_info(media_id)[0] # [0] - потому что функция возвращает массив, где всего один элемент 

media_info — это JSON следующего формата:

Пример полноценного JSONa

Давайте посмотрим как выглядит JSON для поста в инстаграме. Вы можете получить такой же JSON для любой своей публикации, обратившись к боту.

В media_info содержится вся доступная о посте информация, будь это геопозиция, отмеченные пользователи, комментарии и количество лайков.

Ниже пример поста и JSON соответсвующий ему.

< "taken_at": 1584960820, "pk": 2271138434299490600, "id": "2271138434299490618_381142195", "device_timestamp": 1584960663222320, "media_type": 1, "code": "B-EtF98KHE6", "client_cache_key": "MjI3MTEzODQzNDI5OTQ5MDYxOA==.2", "filter_type": 0, "location": < "pk": 500801171, "short_name": "Bolshaya Nikitskaya Street", "facebook_places_id": 103200906400409, "external_source": "facebook_places", "name": "Bolshaya Nikitskaya Street", "address": "", "city": "", "lng": 37.598333333333, "lat": 55.7575 >, "lat": 55.7575, "lng": 37.598333333333, "user": < "pk": 381142195, "username": "oak.raw", "full_name": "ℕ. . ", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/83355342_622022825292167_3709019308832063488_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=dvMUAIilXsIAX9jbV-1&tp=1&oh=7fdc985600993dfa2b1a5da2a117f58c&oe=6011B3AD", "profile_pic_id": "2233042169810667649_381142195", "friendship_status": < "following": true, "outgoing_request": false, "is_bestie": false, "is_restricted": false >, "is_verified": false, "has_anonymous_profile_picture": false, "is_unpublished": false, "is_favorite": false, "latest_reel_media": 1608919065, "account_badges": [], "story_reel_media_ids": [] >, "can_viewer_reshare": true, "caption_is_edited": false, "comment_likes_enabled": true, "comment_threading_enabled": true, "has_more_comments": true, "next_max_id": 18104082043182496, "max_num_visible_preview_comments": 2, "preview_comments": [ < "pk": 17865118795863322, "user_id": 1232001680, "text": "О, магазинус Лебедева:)", "type": 0, "created_at": 1590937324, "created_at_utc": 1590937324, "content_type": "comment", "status": "Active", "bit_flags": 0, "did_report_as_spam": false, "share_enabled": false, "user": < "pk": 1232001680, "username": "juliam_moroz", "full_name": "Julia Moroz", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/130863979_442658400430632_6468083327923303795_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=QoXEey9rFtsAX-KQPXk&tp=1&oh=925b051f9b220184e2c6da8b13dced83&oe=600F1F50", "profile_pic_id": "2463153806610276064_1232001680", "is_verified": false >, "is_covered": false, "media_id": 2271138434299490600, "has_translation": true, "has_liked_comment": false, "comment_like_count": 1, "private_reply_status": 0 >, < "pk": 18104082043182496, "user_id": 381142195, "text": "@juliam_moroz да)", "type": 2, "created_at": 1590937557, "created_at_utc": 1590937557, "content_type": "comment", "status": "Active", "bit_flags": 0, "did_report_as_spam": false, "share_enabled": false, "user": < "pk": 381142195, "username": "oak.raw", "full_name": "ℕ. . ", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/83355342_622022825292167_3709019308832063488_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=dvMUAIilXsIAX9jbV-1&tp=1&oh=7fdc985600993dfa2b1a5da2a117f58c&oe=6011B3AD", "profile_pic_id": "2233042169810667649_381142195", "is_verified": false >, "is_covered": false, "media_id": 2271138434299490600, "parent_comment_id": 17865118795863322, "has_liked_comment": false, "comment_like_count": 0, "private_reply_status": 0 > ], "can_view_more_preview_comments": true, "comment_count": 7, "inline_composer_display_condition": "impression_trigger", "inline_composer_imp_trigger_time": 5, "image_versions2": < "candidates": [ < "width": 1080, "height": 1350, "url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-15/e35/p1080x1080/90302974_101307918155463_880925762909832594_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_cat=103&_nc_ohc=p4i6ab9qK3MAX_Je38D&tp=1&oh=47acaea745cfc8601a20d95e0d847370&oe=6011BB64&ig_cache_key=MjI3MTEzODQzNDI5OTQ5MDYxOA%3D%3D.2", "scans_profile": "e35", "estimated_scans_sizes": [ 34282, 68565, 102848, 137131, 171414, 191812, 244088, 277418, 308546 ] >, < "width": 360, "height": 450, "url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-15/e35/p360x360/90302974_101307918155463_880925762909832594_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_cat=103&_nc_ohc=p4i6ab9qK3MAX_Je38D&tp=1&oh=7911d48a74cbf2c1c05bf0ef5b16e666&oe=60121616&ig_cache_key=MjI3MTEzODQzNDI5OTQ5MDYxOA%3D%3D.2", "scans_profile": "e35", "estimated_scans_sizes": [ 4342, 8685, 13028, 17370, 21713, 26141, 754408, 39084, 39084 ] >] >, "original_width": 1440, "original_height": 1800, "like_count": 108, "has_liked": false, "like_and_view_counts_disabled": false, "top_likers": [ "yar.ok" ], "facepile_top_likers": [ < "pk": 1226384634, "username": "yar.ok", "full_name": "YAROSLAV OKATEV", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/91143836_1482909661889518_2687135057402920960_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=ZAsnt6I4_7sAX88ZA8A&tp=1&oh=88639d9237f3fc4d578890d57e66f21a&oe=601281EA", "profile_pic_id": "2275072905746358933_1226384634", "is_verified": false >, < "pk": 306914465, "username": "nastianastacia", "full_name": "Nastia", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/15802713_1158590314260662_7281072673235402752_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=0lg_5gFmnsUAX-07OSA&tp=1&oh=875accdaf1bc2d1bb72d9442445450a9&oe=6011653B", "profile_pic_id": "1423562998005751579_306914465", "is_verified": false >, < "pk": 236827679, "username": "terzivladida", "full_name": "Терзи Владислав | Фотограф", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/122422351_3763193670359540_4602498721748722003_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=df9YioDKtSsAX8kLHJT&tp=1&oh=952d54cb77d1029bc88070ccaf6d99bb&oe=600FFBAD", "profile_pic_id": "2425286083698432257_236827679", "is_verified": false >], "photo_of_you": false, "usertags": < "in": [ < "user": < "pk": 253581477, "username": "temalebedev", "full_name": "Artemy Lebedev", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/58411085_1127266294129169_3154601655836606464_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=aTk3egGzdp4AX8aexRy&tp=1&oh=b689c9d264aae438a0430d5d34a0c64c&oe=600FB372", "profile_pic_id": "2032755399167097999_253581477", "is_verified": true >, "position": [ 0.6723027252, 0.18760061960000002 ], "start_time_in_video_in_sec": null, "duration_in_video_in_sec": null > ] >, "can_see_insights_as_brand": false, "caption": < "pk": 17866702039715754, "user_id": 381142195, "text": "ТАКС. ДАВНО НИЧЕГО НЕ ПИСАЛ ⠀\n\nТак получается, что по возвращению из путешествий сложно заставить себя что-либо написать и выложить. Нет необходимых инфоповодов, мотивирующих это делать. Нет внутреннего ощущения насыщенности жизни, которое и побуждает делиться классными кадрами и интересным историями. ⠀\n\nВ данном случае в качестве инфоповода послужил классный респиратор.", "type": 1, "created_at": 1584960823, "created_at_utc": 1584960823, "content_type": "comment", "status": "Active", "bit_flags": 0, "did_report_as_spam": false, "share_enabled": false, "user": < "pk": 381142195, "username": "oak.raw", "full_name": "ℕ. . ", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/83355342_622022825292167_3709019308832063488_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=dvMUAIilXsIAX9jbV-1&tp=1&oh=7fdc985600993dfa2b1a5da2a117f58c&oe=6011B3AD", "profile_pic_id": "2233042169810667649_381142195", "friendship_status": < "following": true, "outgoing_request": false, "is_bestie": false, "is_restricted": false >, "is_verified": false, "has_anonymous_profile_picture": false, "is_unpublished": false, "is_favorite": false, "latest_reel_media": 1608919065, "account_badges": [], "story_reel_media_ids": [] >, "is_covered": false, "media_id": 2271138434299490600, "has_translation": true, "private_reply_status": 0 >, "can_viewer_save": true, "organic_tracking_token": "eyJ2ZXJzaW9uIjo1LCJwYXlsb2FkIjp7ImlzX2FuYWx5dGljc190cmFja2VkIjp0cnVlLCJ1dWlkIjoiYTk2MWE2OWMzY2ViNDQ2NGE1NDMzMWRlMjNiNWEyODAyMjcxMTM4NDM0Mjk5NDkwNjE4Iiwic2VydmVyX3Rva2VuIjoiMTYwODk5MzA4ODMxMXwyMjcxMTM4NDM0Mjk5NDkwNjE4fDQ1Mzc1MjU2NzQzfDgxMzI2NWY4YzM2MmIwZDVhMzg3ZTdmNWQ2YjlmYmQyNmQ3ODQ5NzUzMWIzYTk0ZDhkM2VlZmUzNTVkMjQ4MzEifSwic2lnbmF0dXJlIjoiIn0=", "sharing_friction_info": < "should_have_sharing_friction": false, "bloks_app_url": null >, "is_in_profile_grid": false, "profile_grid_control_enabled": false, "is_shop_the_look_eligible": false, "deleted_reason": 0, "integrity_review_decision": "pending" >

Для постов другого формата

В постах содержащих видео или несколько изображений (карусель) содержатся ещё такие поля:

"video_versions" "video_duration" "carousel_media" "number_of_qualities" "title" "video_dash_manifest" "view_count" "product_type" "video_codec" "is_post_live" "media_cropping_info" "thumbnails" "is_dash_eligible" "carousel_media_count" "has_audio" "nearly_complete_copyright_match"

Как уже было замечено ранее, в media_info содержится вся доступная о посте информация, будь это геопозиция, отмеченные пользователи, комментарии (а если быть точным их превью, preview_comments ) и количество лайков.

Ниже расшифровка для некоторых полей:

  • taken_at , pk , id , device_timestamp — время создания поста и его идентификаторы.
  • media_type — тип контента внутри поста. Одно изображение / несколько изображений / видео / пост в IGTV.
  • location , lng , lat — всё что относится к геопозиции, указанной в посте. Объект location содержит информацию о геотеге (например facebook_places_id , address , city ), lng и lat — координаты геотега. Интересно кстати, что координаты дублируются, они есть как в объекте location , так и в самом media_info .
  • usertags — объект, содержащий информацию об отмеченных пользователях.

Давайте посмотрим на некоторые необычные поля, которые также есть в этом JSON. Больше всего меня смутили два поля — top_likers и facepile_top_likers . Как оказалось, это лайки тех пользователей, которые отображаются непосредственно до количества лайков («Нравится username и еще N пользователям», в мобильной версии есть еще три маленьких круглых картинки до этой надписи). Готов предположить, что Instagram показывает таким образом лайки тех пользователей, которых он считает наиболее интересными и важными для нас.

top_likers содержит в себе только один username и используется для текстовой аннотации. facepile_top_likers отвечает за визуальную аннотацию лайков, этот объект содержит в себе три профиля пользователей, где у каждого профиля указана ссылка на его аватарку ( profile_pic_url ).

Как это выглядит?

Интересно, кстати, что media_info содержит поле organic_tracking_token . Как утверждает Инстраграм — таким образом происходит поддержка брендов, занимающихся производством органической продукции.

А какие данные можно получить о пользователе?

Посмотрим, какую информацию Instagram предоставляет о нас — рядовых пользователях. На примере моего любимого фотографа.

Такая структура данных содержит основные данные о профиле (в том случае, если он открытый, если профиль закрытый — то данных будет гораздо меньше). Также тут есть некоторые поля для отображения общих подписчиков. Ещё в такой структуре данных Инстаграм может присылать список аккаунтов, на которые он рекомендует вам подписаться.

 < "pk": 566674424, "username": "shortstache", "full_name": "Garrett King", "is_private": false, "profile_pic_url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s150x150/130951392_133135768583933_6026107970965456642_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=gmxi213GpY4AX8cbdpz&tp=1&oh=ad1ca4820958615dc5e99859ef101b1d&oe=60134F33", "profile_pic_id": "2463797374104100463_566674424", "is_verified": false, "has_anonymous_profile_picture": false, "media_count": 2594, "geo_media_count": 0, "follower_count": 485647, "following_count": 1090, "following_tag_count": 0, "biography": "?Huntington Beach, CA\nBehind the scenes @longstache \ninfo@shortstache.com", "biography_with_entities": < "raw_text": "?Huntington Beach, CA\nBehind the scenes @longstache \ninfo@shortstache.com", "entities": [ < "user": < "id": 2264445914, "username": "longstache" >> ] >, "external_url": "http://santogallery.com/garrett-king", "external_lynx_url": "https://l.instagram.com/?u=http%3A%2F%2Fsantogallery.com%2Fgarrett-king&e=ATOlDiBCCUHXljpYDutSTWgfd8g3dL5JwubDPnxKKowaNqriJSOcQSmZoZp6cEyK1gYK5DnB3Zo5UXaFQfTISio&s=1", "total_igtv_videos": 30, "has_igtv_series": false, "total_clips_count": 1, "total_ar_effects": 0, "usertags_count": 7399, "is_favorite": false, "is_favorite_for_stories": false, "is_favorite_for_igtv": false, "is_favorite_for_highlights": false, "live_subscription_status": "default", "is_interest_account": true, "has_chaining": true, "hd_profile_pic_versions": [ < "width": 320, "height": 320, "url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s320x320/130951392_133135768583933_6026107970965456642_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=gmxi213GpY4AX8cbdpz&tp=1&oh=2947433220502b82b19ddc9c7931bb43&oe=601512CB" >, < "width": 640, "height": 640, "url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/s640x640/130951392_133135768583933_6026107970965456642_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=gmxi213GpY4AX8cbdpz&tp=1&oh=43803ae7d9967b4195b1b6751227723f&oe=60161EF2" >], "hd_profile_pic_url_info": < "url": "https://scontent-hel3-1.cdninstagram.com/v/t51.2885-19/130951392_133135768583933_6026107970965456642_n.jpg?_nc_ht=scontent-hel3-1.cdninstagram.com&_nc_ohc=gmxi213GpY4AX8cbdpz&oh=b8f622f8d82b633018a28b4c5b59b24b&oe=6016354B", "width": 1080, "height": 1080 >, "mutual_followers_count": 1, "profile_context": "Followed by oak.raw", "profile_context_links_with_user_ids": [ < "start": 12, "end": 19, "username": "oak.raw" >], "profile_context_mutual_follow_ids": [ 381142195 ], "show_shoppable_feed": false, "shoppable_posts_count": 0, "can_be_reported_as_fraud": false, "merchant_checkout_style": "none", "seller_shoppable_feed_type": "none", "has_highlight_reels": true, "has_guides": false, "is_eligible_for_smb_support_flow": true, "displayed_action_button_partner": null, "smb_delivery_partner": null, "smb_support_partner": null, "smb_donation_partner": null, "smb_support_delivery_partner": null, "displayed_action_button_type": "", "direct_messaging": "", "address_street": "", "business_contact_method": "", "category": "Photographer", "city_id": 0, "city_name": "", "contact_phone_number": "", "is_call_to_action_enabled": false, "latitude": null, "longitude": null, "public_email": "info@shortstache.com", "public_phone_country_code": "", "public_phone_number": "", "zip": "", "instagram_location_id": "", "is_business": false, "account_type": 3, "professional_conversion_suggested_account_type": 3, "can_hide_category": true, "can_hide_public_contacts": true, "should_show_category": true, "should_show_public_contacts": true, "account_badges": [], "whatsapp_number": "", "include_direct_blacklist_status": true, "is_potential_business": true, "show_post_insights_entry_point": true, "is_bestie": false, "has_unseen_besties_media": false, "show_account_transparency_details": true, "auto_expand_chaining": false, "highlight_reshare_disabled": false, "is_memorialized": false, "open_external_url_with_in_app_browser": true >

Как скачать изображение

Для того чтобы скачать изображение необходимо найти в этом JSON ссылку на фотографию, которая хранится либо в image_versions2 , в случае когда в посте всего одна фотография, либо в carousel_media , когда в посте фотографии несколько. carousel_media содержит в себе изображения, которые хранятся в виде объектов image_versions2

Пример объекта image_versions2 :

Можно заметить, что Инстаграм хранит у себя две версии фотографии: большего и меньшего разрешения. Судя по всему, фотография меньшего разрешения нужна для того чтобы отображать пост в ленте.

Так как в библиотеке не работала функция загрузки изображений, я написал свой вариант. Тут учтено, что в одном посте может быть как одна, так и несколько фотографий. Если же пост содержит видео, то этот код скачает фотографию, которая стоит на обложке видео.

""" filename goes without an extention """ import requests def donwnload_photo(media_id, filename): media = bot.get_media_info(media_id)[0] if ("image_versions2" in media.keys()): url = media["image_versions2"]["candidates"][0]["url"] response = requests.get(url) with open(filename + ".jpg", "wb") as f: response.raw.decode_content = True f.write(response.content) elif("carousel_media" in media.keys()): for e, element in enumerate(media["carousel_media"]): url = element['image_versions2']["candidates"][0]["url"] response = requests.get(url) with open(filename + str(e) + ".jpg", "wb") as f: response.raw.decode_content = True f.write(response.content) 

Представим себе ситуацию, что мы хотим скачать некоторое количество изображений из профиля фотографа, который нам нравится:

twony_last_medias = bot.get_user_medias("shortstache", filtration = None) for e,media_id in enumerate(twony_last_medias): donwnload_photo(media_id, "img_" + str(e))

Несколько загруженных таким образом фотографий невероятного shortstache. Удивительно, насколько Инстаграм сжал эти фотографии без видимой потери качества.

Всего 160 KbВсего 119 Kb278 Kb

Outro

С каждым часом, проведённым в социальных сетях, мы предоставляем информационным компаниям всё больше и больше информации о себе. А развитие технологий анализа этих данных позволяет уже не просто знать что-то о нас и нашем поведении, но и предсказывать наши наиболее вероятные действия, или даже ненавязчиво влиять на процесс совершения этих действий. Если честно, то меня всегда завораживала та сила, которая есть у компаний, возможно, знающих о нас больше, чем мы сами.

Надеюсь, у меня получилось вдохновить вас на какой-нибудь интересный проект, базирующийся на данных из Instagram. Лично у меня чешутся руки поискать какие-нибудь нетривиальные закономерности, например, сравнить как отличается контент и геотеги публикаций travel блоггеров за 2019 и 2020 год. Ммм, А если ещё и прикрутить куда-нибудь нейросетки и попробовать самому сделать рекомендательную систему для классных фотографий (не зря же два года CV занимался). Ненавязчиво оставлю ссылку на мой телеграм канал, где я буду писать про дальнейшие свои изыскания в этой области.

К слову, если вы вдруг будете делать что- то связанное с Instagram, то вот максимально актуальная на сегодняшний день библиотека.

Как получить данные из Instagram с помощью Python — Парсинг Инстаграм

Инстаграм парсинг

Instagram — одна из самых популярных социальных сетей с миллиардами пользователей. Парсинг Инстаграм имеет огромную ценность для компаний, маркетологов и частных лиц. Любой может использовать эти данные для анализа данных, целевого маркетинга и получения информации.

Вы можете использовать Python для создания автоматизированного инструмента, который извлекает данные из Instagram. И в этом поможет удивительная библиотека Instaloader

Установка необходимых библиотек

Instaloader — это библиотека Python, которую вы можете использовать для извлечения общедоступных данных из Instagram. Вы можете получить доступ к данным, таким как изображения, видео, имя пользователя, количество постов, количество подписчиков, биографию и т. д. Обратите внимание, что Instaloader никоим образом не связан, не авторизован и не поддерживается Instagram.

Чтобы установить instaloader через pip, выполните следующую команду:

pip install instaloader

Далее вам нужно установить библиотеку Pandas.

Pandas — это библиотека Python, которая в основном используется для обработки и анализа данных. Выполните следующую команду, чтобы установить ее:

pip install pandas

Теперь вы готовы приступить к настройке кода и извлечению данных из Instagram.

Парсинг Инстаграм — Настройка кода

Чтобы настроить инструмент получения данных из Instagram, вам необходимо импортировать библиотеку Instaloader Python и создать экземпляр класса Instaloader. После этого вам нужно предоставить дескриптор Instagram профиля, из которого вы хотите извлечь данные.

import instaloader
# Creating an instance of the Instaloader class
bot = instaloader . Instaloader ( )
# Loading the profile from an Instagram handle
profile = instaloader . Profile . from_username ( bot . context , ‘cristiano’ )
print ( profile )

Это хороший первый шаг, чтобы проверить основы работы. Вы должны увидеть некоторые значимые данные без ошибок:

Извлечение данных из профиля

Вы можете извлечь общедоступные данные, такие как имя пользователя, количество сообщений, количество подписчиков, количество подписок, биографию, идентификатор пользователя и внешний URL-адрес с помощью Instaloader. Вам нужно только предоставить дескриптор Instagram профиля.

Больше статей: Автоматический подписчик в Instagram – Instagram Auto Follower
import instaloader
import pandas as pd
# Creating an instance of the Instaloader class
bot = instaloader . Instaloader ( )
# Loading a profile from an Instagram handle
profile = instaloader . Profile . from_username ( bot . context , ‘leomessi’ )
print ( «Username: » , profile . username )
print ( «User ID: » , profile . userid )
print ( «Number of Posts: » , profile . mediacount )
print ( «Followers Count: » , profile . followers )
print ( «Following Count: » , profile . followees )
print ( «Bio: » , profile . biography )
print ( «External URL: » , profile . external_url )

Вы должны увидеть много информации о профиле из указанного вами дескриптора:

Парсинг Инстаграм

Извлечение электронных писем из биографии

Вы можете извлечь адреса электронной почты из биографии Instagram любого профиля, используя регулярные выражения. Вам нужно импортировать библиотеку Python re и передать регулярное выражение для проверки электронной почты в качестве параметра методу re.findall():

import instaloader
# Creating an instance of Instaloader class
bot = instaloader . Instaloader ( )
profile = instaloader . Profile . from_username ( bot . context , «wealth» )
print ( «Username: » , profile . username )
print ( «Bio: » , profile . biography )
emails = re . findall ( r «\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]<2,>\b» , profile . biography )
print ( «Emails extracted from the bio:» )
print ( emails )

Скрипт напечатает все, что он распознает как адрес электронной почты в биографии:

Извлечение данных о лучших результатах поиска

Когда вы ищете что-либо в Instagram, вы получаете несколько результатов, включая имена пользователей и хэштеги. Вы можете извлечь лучшие результаты поиска, используя методы get_profiles() и get_hashtags(). Вам нужно только указать поисковый запрос в методе instaloader.TopSearchResults(). Кроме того, вы можете повторять и печатать/сохранять отдельные результаты.

import instaloader
# Creating an instance of the Instaloader class
bot = instaloader . Instaloader ( )
# Provide the search query here
search_results = instaloader . TopSearchResults ( bot . context , ‘music’ )
# Iterating over the extracted usernames
for username in search_results . get_profiles ( ) :
print ( username )
# Iterating over the extracted hashtags
for hashtag in search_results . get_hashtags ( ) :
print ( hashtag )
Больше статей: Работа с файлами CSV в Python

Извлечение подписчиков и подписчиков учетной записи

Вы можете извлечь подписчиков учетной записи и тех, на кого он подписан. Для этого нужно будет залогиниться, поэтому укажитедет свои логин и пароль, чтобы получить эти данные.

Внимение:
Никогда не используйте свои личные учетные записи для извлечения данных из Instagram, так как это может привести к временной или постоянной блокировке вашей учетной записи.

После создания экземпляра класса Instaloader вам необходимо указать свое имя пользователя и пароль. Это делается для того, чтобы бот мог войти в Instagram, используя вашу учетную запись, и получить данные о подписчиках и подписках.

Затем вам нужно предоставить дескриптор Instagram целевого профиля. Методы get_followers() и get_followees() извлекают подписчиков и подписчиков. Вы можете получить имена пользователей подписчиков и подписчиков, используя свойства follower.username и Followee.username соответственно.

Если вы хотите сохранить результаты в файле CSV, вам сначала нужно преобразовать данные в объект Pandas DataFrame. Используйте метод pd.DataFrame() для преобразования объекта списка в DataFrame.

Наконец, вы можете экспортировать объект DataFrame в файл CSV, используя метод to_csv(). Вам необходимо передать имя файла.csv в качестве параметра этому методу, чтобы получить экспортированные данные в формате файла CSV.

Внимение:
Только владельцы аккаунтов могут видеть всех подписчиков и подписчиков. Вы не сможете извлечь все данные о подписчиках и подписках, используя этот или любой другой метод.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *