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

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

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

И хотя Facebook недавно выпустил новый Instagram API, они поддерживают только бизнес-клиентов.

Но эй, это не проблема, - подумал я, - я могу создать свой собственный.

И это именно то, что мы узнаем сегодня.

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

А когда есть желание, есть выход.

Вот тут и появляется Кукольник. Библиотека позволяет нам создать безголовый экземпляр Google Chrome / Chromium и управлять им с помощью протокола DevTools.

Настройка проекта

Вы можете скопировать репозиторий.

git clone https://github.com/maciejcieslar/instagrambot.git

Наша структура выглядит так:

|  -- instagrambot/
|  |  -- .env
|  |  -- .eslintrc.js
|  |  -- .gitignore
|  |  -- README.md
|  |  -- package-lock.json
|  |  -- package.json
|  |  -- src/
|  |  |  -- common/
|  |  |  |  -- browser/
|  |  |  |  |  -- api/
|  |  |  |  |  |  -- authenticate.ts
|  |  |  |  |  |  -- comment-post.ts
|  |  |  |  |  |  -- find-posts.ts
|  |  |  |  |  |  -- follow-post.ts
|  |  |  |  |  |  -- get-following.ts
|  |  |  |  |  |  -- get-post-info.ts
|  |  |  |  |  |  -- get-user-info.ts
|  |  |  |  |  |  -- index.ts
|  |  |  |  |  |  -- like-post.ts
|  |  |  |  |  |  -- unfollow-user.ts
|  |  |  |  |  -- index.ts
|  |  |  |  -- interfaces/
|  |  |  |  |  -- index.ts
|  |  |  |  -- scheduler/
|  |  |  |  |  -- index.ts
|  |  |  |  |  -- jobs.ts
|  |  |  |  -- scraper/
|  |  |  |  |  -- scraper.js
|  |  |  |  -- utils/
|  |  |  |  |  -- index.ts
|  |  |  |  -- wit/
|  |  |  |  |  -- index.ts
|  |  |  -- config.ts
|  |  |  -- index.ts
|  |  -- tsconfig.json
|  |  -- tslint.json

Браузерный интерфейс

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

Наша функция getPage создает для нас страницу браузера, переходит по предоставленному URL-адресу и внедряет наш парсер (упоминается позже). Кроме того, он ожидает, пока наш обратный вызов вернет обещание, разрешит его и закроет страницу.

Src / common / browser / index.ts

Чтобы быть совершенно ясным, Puppeteer сам по себе является интерфейсом браузера, мы просто абстрагировали некоторый код, который будет постоянно повторяться.

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

Скребок

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

Сначала мы определяем несколько помощников, в основном для установки атрибутов данных. Помимо этого, у нас есть этот класс Element, который является абстракцией по сравнению с обычным HTMLElement. Кроме того, есть функция поиска, которая дает нам более удобный для разработчиков способ запроса элементов.

Src / common / scraper / scraper.js

Аутентификация

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

Сначала мы ждем открытия страницы, затем вводим свои учетные данные, указанные в config.ts. Между каждым символом есть задержка 100 мс. Затем мы берем кнопку Войти и, если она существует, нажимаем на нее.

Src / common / browser / api / Authenticate.ts

Если вы хотите увидеть волшебство, установите в параметрах запуска Puppeteer без головы значение false. Он откроет браузер и будет отслеживать каждое действие, которое совершает наш бот.

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

Мы можем закрыть страницу (наш интерфейс позаботится об этом) и перейти к созданию нашей первой функции для поиска сообщений с #hashtag.

URL-адрес Instagram для последних сообщений с хэштегом: https://www.instagram.com/explore/tags/follow4follow.

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

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

При первой загрузке появляется 9 верхних и 12 обычных сообщений. Всего 21. Если бы мы хотели найти 36 сообщений и опустить первые 9, нам пришлось бы вычесть первые 12, а затем разделить оставшиеся на 12, чтобы мы знали, сколько раз нам нужно прокручивать.

36 (всего) - 12 (первые) = 24 (недостающие посты)

24/12 = 2 (время, которое нам нужно прокрутить)

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

Src / common / browser / api / find-posts.ts

Мы можем перебирать возвращенные URL-адреса и выполнять заданный набор действий для каждого из них.

Дело в том, что мы ничего не знаем о публикации, кроме ее URL, но мы можем найти всю необходимую информацию, очистив ее.

Получение информации о посте

Как мы видим выше, на сайте есть много полезной информации о публикации, такой как:

  • За автором следят?
  • Селектор кнопки следования
  • Пост понравился?
  • Селектор кнопки Like
  • Имя пользователя автора
  • Описание и комментарии
  • Селектор комментариев
  • Количество лайков

Но прежде чем мы продолжим ...

Добавление НЛП для наших комментариев

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

В идеале мы хотели бы знать, о чем идет речь. Вот как мы можем это сделать:

Wit.ai - это сервис от Facebook, который позволяет нам создать приложение и научить его понимать предложения.

Вот откуда пришло НЛП, это расшифровывается как обработка естественного языка. Он также включен в Messenger API, например, если вы когда-нибудь захотите создать чат-бота.

Хотя это может занять некоторое время, мы можем научить наше приложение понимать описание сообщения и давать нам идеи.

На самом деле это очень просто, все, что нам нужно сделать, это сказать ему, что искать в предложении. В нашем случае предложением будет описание поста, которое мы отправим с библиотекой node-wit.

Во-первых, вам необходимо создать учетную запись на wit.ai. Вы можете использовать свою учетную запись GitHub для входа в систему.

Затем вы можете создать собственное приложение или использовать чужое. Если вы хотите использовать мое обученное приложение, здесь.

Наше приложение принимает сообщение и возвращает его значение - happy_description или sad_description и насколько уверенно оно в нем.

Также есть библиотека смайлов, чтобы сделать наши комментарии более живыми.

Теперь давайте поместим наш токен в config.ts и сделаем небольшой помощник для преобразования сообщений в намерения и создания комментариев на основе предоставленного намерения.

Src / common / wit / index.ts

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

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

Src / common / browser / api / get-post-info.ts

Получение информации о пользователях

Мы можем извлечь из поста лишь ограниченное количество информации. Иногда нам может быть интересен профиль пользователя.

Мы можем почерпнуть много полезной информации, такой как:

  • Количество постов
  • Количество подписчиков
  • Количество следующих
  • За аккаунтом следят?
  • Био (описание), но поскольку это нам ни к чему, мы не собираемся отказываться от него.

Src / common / browser / api / get-user-info.ts

Действия с публикациями

А пока нам нужно реализовать like-post.ts.

Мы просто проверяем, понравился ли пост уже. Если нет, берем селектор лайков и нажимаем на него.

Src / common / browser / api / like-post.ts

То же самое и с follow-post.ts.

Src / common / browser / api / follow-post.ts

С помощью comment-post.ts мы вводим комментарий в текстовое поле и нажимаем Enter.

Src / common / browser / api / comment-post.ts

Действия пользователей

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

Во-первых, нам нужно получить URL-адреса людей, на которых мы подписаны.

Мы нажимаем кнопку подписаться в нашем профиле.

Должен появиться список с последними 20 пользователями, за которыми мы следили. Затем мы можем выполнить unfollow-user.ts для каждого URL-адреса.

Src / common / browser / api / get-following.ts

Теперь, когда у нас есть URL-адреса, мы просто отписываемся от одного пользователя за раз. Мы нажимаем кнопку отмены подписки, а затем щелкаем диалоговое окно подтверждения.

Src / common / browser / api / unfollow-user.ts

Планировщик

Теперь, когда все готово, мы должны подумать о том, как будет работать наш бот.

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

Судя по тому, что я читал и видел во время собственных тестов, существуют разные ограничения в зависимости от размера учетной записи и возраста.

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

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

Src / common / scheduler / index.ts

Src / common / scheduler / jobs.ts

Как вы могли заметить, мы использовали множество переменных из конфигурации. Есть некоторые значения, которые мы предоставляем с proccess.env, что означает, что они чувствительны, и мы должны включить их в файл .env. Остальное можно изменить вручную.

Src / config.ts

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

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ

В соответствии с политикой Instagram в отношении robots.txt такое приложение запрещено запускать. Сообщение предназначено только для образовательных целей.

Src / index.ts

npm run start

Большое спасибо за чтение, надеюсь, вам понравилось!

Если у вас есть какие-либо вопросы или комментарии, не стесняйтесь оставлять их в разделе комментариев ниже или отправьте мне сообщение.

Следуйте за мной в твиттере @maciejcieslar.

Присоединяйтесь к моей рассылке новостей!

Первоначально опубликовано на www.mcieslar.com 10 июля 2018 г.