Парсинг постов и их статистики в Instagram при помощи кода на Python

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

Код использует API инструменты от LevPasha. GitHub


UPDATE 03.09.2020

Внимание! На данный момент страница проекта на GitHub удалена, а инструменты для вытаскивания ID аккаунтов, описанные в статье, не работают. Сама библиотека еще работает, но ее работу нужно изучать.

Небольшие аккаунты в районе 1000-2000 постов собираются быстро, как раньше, и без видимых усилий.

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


UPDATE 06.09.2020 — Как самостоятельно получить ID аккаунта в Instagram

  1. Открываем страницу нужным аккаунтом в Google Chrome.
  2. Щелкаем правой кнопкой, просмотреть код страницы. (F12 на Windows; ⌥+⌘+i на Mac OS)
  3. Там переключаемся в консоль (Console) при помощи кнопки внизу, и вводим в консоли window._sharedData.config.viewerId
  4. Нажимаем Enter
  5. Если получили ошибку — перезагружаем страницу.
  6. На выходе получаем ID аккаунта, можно вставлять в код парсера и парсить!

Для начала — немного об использовании официального API от Instagram. С 15 октября 2019 года регистрация новых клиентов через Instagram Developer прекращена, и не предвидится. Если вы успели зарегистрироваться раньше — доступ еще есть, но вам потребуется получить расширенные права через подтверждение приложения. Без них вы сможете скачать данные только по 20 последним публикациям, не более. Если не зарегистрированы, вам доступен API Instagram Basic Display. О его возможностях можно почитать по ссылке. Факт в том, что официальный API требует подтверждения вас, как доверенного лица от Instagram.

Этих проблем позволяет избежать использование неофициальных API. И самый популярный из них — упомянутый выше Instagram-API-python от LevPasha. API написан на Python, так что для взаимодействия с ним мы так же будем использовать Python.

В разделе Examples на GitHub LevPasha можно найти примеры кода для загрузки контента в инсту, для массового удаления своего контента, и еще много полезных фич. Советую ознакомиться.

Покончили с прелюдией, начинаем.

Подготовка

Вам потребуется установленный язык Python на вашей системе. Так как в своей работе я использую язык R и Python для анализа данных, то рекомендую Anaconda — дистрибутив языков программирования Python и R, включающий набор популярных свободных библиотек, объединённых темой науки о данных и машинного обучения. Дистрибутив скачивается единожды, и вся последующая конфигурация, в том числе установка дополнительных модулей, может проводится в офлайне.

Последнюю версию дистрибутива можете найти здесь. Скачивайте версию для Python 3.7, устанавливайте и запускайте Jupyter. Процесс создания проекта на сложный, вам всего лишь нужно определиться с рабочей директорией и создать там новую записную книжку Jupyter Notebook.

Никто так же не запрещает вам использовать терминал с Python или любой другой способ взаимодействовать с кодом.

Установка Instagram-API-python

Все инструкции по установке можно найти на странице Instagram-API-python в GitHub LevPasha. Там же вы найдете условия и ограничения по использованию API.

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

Новый поддельный аккаунт Instagram с неподтвержденным номером телефона через 1-24 часа будет заблокирован и не сможет выполнять никаких запросов. Все запросы будут перенаправлены на страницу https://instagram.com/challenge.

Кстати, сам проект от LevPasha, по сути, представляет собой Python-порт другого проекта кастомной API, написанного на PHP.

После установки Python (в составе Conda или отдельно), запустите консоль. Сначала копируем содержимое Instagram-API-python в GitHub LevPasha.

git clone https://github.com/LevPasha/Instagram-API-python.git

Переходим в только что скачанный каталог:

cd Instagram-API-python

Устанавливаем зависимые файлы и библиотеки: (необязательно, нужно только если соберетесь закачивать в инсту фотки или видео)

pip install -r requirements.txt

Далее устанавливаем сам InstagramApi через pip. В консоли выполняем:

pip install InstagramApi

Или

py -m install InstagramApi

Готово. После этого вы сможете вызывать API от LevPasha в любом коде на Python через команду

from InstagramAPI import InstagramAPI

Скачиваем контент любого Instagram аккаунта

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

Для начала импортируем необходимые библиотеки. InstagramAPI уже должен быть установлен по инструкции выше.

from InstagramAPI import InstagramAPI
import time
import sys
import traceback
import pandas as pd
import datetime

Если вы не устанавливали зависимые библиотеки, то после выполнения появится сообщение Fail to import moviepy. Need only for Video upload. Значит, все загрузилось нормально, кроме модуля moviepy который вам не понадобится в данной инструкции.

После этого прогоняем следующую часть кода. Это и есть та часть, которая запускает сбор данных. В ней обращаем внимание на функцию time.sleep(10). Она будет ставить на 10-секундную паузу процесс в случае ошибки.

class MyInstaCrawler(InstagramAPI):
    """
    Want to have a direct control over the instaAPI. When the users are loaded from api, the best way is to store
    them in the queue, where it would have listeners - parsers that would do next job.
    """

    def __init__(self, username, password):
        super().__init__(username, password)

    def getTotalFollowers(self, usernameId):
        import datetime
        next_max_id = ''
        followers = []
        while 1:
            try:
                if self.getUserFollowers(usernameId, next_max_id):
                    temp = self.LastJson
                    for item in temp["users"]:
                        followers.append(item)
                    print('Followers: %s ' % len(followers))
                    temp['collected_date'] = datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
                    if temp.get("big_list") is None:
                        return followers
                    elif temp['big_list'] is False:
                        return followers
                    next_max_id = temp["next_max_id"]
            except:
                print(traceback.format_exc())
                print("Sleeping 10 secs")
                time.sleep(10)

После этого ваша программа ожидает ввода инструкций. Внимательно посмотрим на следующую часть кода.

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

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

Далее, в поле args вставляем ID аккаунтов, от которых мы хотим получить контент, стату и мотоцикл. Как узнать ID аккаунта? При помощи специальных сервисов. Вот несколько бесплатных:

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

ВАЖНО. Аккаунт, из-под которого осуществляется вход в систему, должен быть подписан на скрытые аккаунты, с которых предполагается скачивание данных. Если вы хотите скачать данные по закрытому аккаунту, а аккаунт для авторизации на него не подписан (и, соответственно, не имеет разрешение на просмотр контента), то код вылетит с ошибкой.

Так происходит, потому что, фактически, Instagram API от LevPasha представляет из себя эмулятор приложения Instagram для Android. Он заходит на каждый аккаунт в каждый пост, читает и записывает то что видит в таблицу. Просто делает это очень быстро. Если вы не можете зайти на этот аккаунт из-за его настроек приватности, получить доступ к его контенту будет нельзя.

Внимательно перепроверяем все настройки. Стоят ли кавычки вокруг каждого ID аккаунта? Запятые? Фигурная скобка в конце?

Если все окей, то запускаем последнюю часть кода.

usr = "Instagram_Login"
pasw = "Instagram_Password"
ic = MyInstaCrawler(usr, pasw)
ic.login()
args = ["отдельные", "айдишки", "каждого", "аккаунта", "для", "парсинга", "в кавычках через запятую"]
total_results = []
for arg in args:
    try:
        arg = int(arg)
        results = ic.getTotalUserFeed(arg)
        if results is None:
            print('Some problems with id %s. No results.' % arg)
            continue
        print('Gathered %s media, saving...' % len(results))
        if len(results) != 0:
            username = results[0]['user']['username']
            for r in results:
                try:
                    reduced_r = {}
                    date = datetime.datetime.fromtimestamp(r['taken_at'])
                    date = date.strftime("%Y-%m-%d"'T'"%H:%M:%S"'Z')
                    caption = r['caption']
                    caption_text = ''
                    if caption is not None:
                        caption_text = caption['text']
                    view_count = 0
                    if r['media_type'] == 2:
                        if r.get('view_count'):
                            view_count = int(r['view_count'])
                    reduced_r['created_time'] = date
                    reduced_r['user.username'] = username
                    reduced_r['caption.text'] = caption_text
                    reduced_r['likes.count'] = r['like_count']
                    reduced_r['video_views'] = view_count
                    reduced_r['comments.count'] = r['comment_count']
                    reduced_r['link'] = 'https://instagram.com/p/' + r['code']
                    total_results.append(reduced_r)
                except Exception as e:
                    print(e)
            print('Finished for %s, id: %s' % (username, arg))
    except ValueError:
        print("Pass ID as an argument. Couldn't transform to int")
    except:
        print(traceback.format_exc())
df = pd.DataFrame(total_results)
df.to_csv('Database %s.csv' % datetime.datetime.now().strftime("%Y-%m-%d,%H:%M:%S"))

Процесс начнется с серии ошибок логина, после чего вы получите надпись об успешном логине. После этого начнется процесс сбора постов. Выглядеть будет как то так:

Request return 405 error!
{'message': '', 'status': 'fail'}
Request return 404 error!
Login success!

Gathered 18 media, saving...
Finished for ваш аккаунт, id: айди вашего аккаунта

Если увидите ошибку Pass ID as an argument. Couldn’t transform to int, перепроверьте, точно ли каждый ID находится в кавычках, и нет ли лишних или отсутствующих запятых.

После окончания процесса, готовая таблица появится в том же каталоге, в котором запускался код, с названием «Database (текущие дата и время).csv».

Готово! По возникающим вопросам, можете писать комментарии под этим постом на Open SMM Asia, или же в мой Facebook.

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

Сабақ тэгі: api, instagram, levpasha, parsing
Артқа: Исследование данных в Digital маркетинге