CoderCastrov logo
CoderCastrov
Парсер

Парсинг результатов поиска Google (без проблем с блокировкой IP)

Парсинг результатов поиска Google (без проблем с блокировкой IP)
просмотров
5 мин чтение
#Парсер

Метод парсинга, устойчивый к блокировке IP

Отказ от ответственности: используйте предложенные здесь идеи на свой страх и риск.

Проблема блокировки IP

Если вы занимаетесь парсингом веб-сайтов, то, вероятно, знаете, что сайты не любят автоматические боты, которые посещают их только для сбора информации. Они настроили системы, которые могут определить, что ваша программа не является реальным человеком, и после нескольких запросов, поступающих из вашего скрипта, обычно появляется ужасное сообщение HTTP 429 Too Many Requests Error. Это означает, что ваш IP-адрес был заблокирован на определенное время. Ваш бот может идти домой и плакать.

Парсинг Святого Грааля

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

Побеждайте свои битвы изнутри

Идея очень проста и может быть сформулирована несколькими ключевыми моментами:

  • Если вы напрямую парсите Google Search, вас поймают через некоторое время и вы получите ошибку HTTP 429.
  • Google App Engine позволяет развертывать сервисы в облаке. Вместо их запуска на конкретном хосте они динамически распределяются по машинам, называемым контейнерами.
  • Каждый раз, когда вы повторно развертываете свой сервис, он находится в другом контейнере с другим IP-адресом.
  • Мы можем создать парсер и запустить его из App Engine. Когда нас поймают, мы сохраняем состояние, повторно развертываем наш парсер и продолжаем парсить с нового контейнера.

Архитектура системы

Хорошо, как мы собираемся это делать? Мы будем использовать модель "мастер-слейв" для архитектуры. Слейв будет развернут в облаке и будет выполнять задачи парсинга по требованию. Мастер будет находиться на вашем локальном компьютере и будет оркестрировать слейва (или слейвов, хотя мы не пойдем так далеко), отправляя задачи.

Когда слейв в конечном итоге не справится с задачей из-за ошибки "Слишком много запросов", мастер уничтожит его и развернет нового слейва, который продолжит задачу. Поскольку у него будет новый IP-адрес, Google не узнает его как предыдущий парсер. (Я только что понял, что все это может показаться довольно непонятным для людей, не знакомых с жаргоном. Пожалуйста, не поймите меня неправильно и ознакомьтесь с моделью "мастер-слейв")

В общем, картинка стоит тысячи слов.

Архитектура парсера на основе модели мастер-слейв

Реализация на практике

Сначала нам нужно настроить проект в Google Cloud. Только после этого мы сможем создать Мастер и Слейв.

Настройка Google Cloud

Я не буду вдаваться в подробности, но для начала вам нужно настроить Google Cloud и выполнить несколько действий:

Создание Slave

Наш Slave будет использовать Flask в качестве основы для коммуникации и объект Scraper для выполнения основной работы. Оба (приложение Flask и Scraper) будут работать в отдельных процессах и обмениваться данными через Pipe. Приложение Flask будет использовать его для отправки запрошенных заданий Scraper'у, а Scraper будет отвечать со своим состоянием при изменении.

Класс Slave

Как вы можете видеть в методе scrape, Slave просто использует объект Scraper(), который получает задание (словарь с параметрами, которые нигде не определены) и возвращает DataFrame. Это дает много свободы для реализации Scraper() по вашему усмотрению. Для Scraper'а, который я написал в качестве примера (здесь), задание определяется следующим образом:

job = {"query": "Футбол", "start": "2020-01-01", "end": "2020-03-29"}

Когда мой Scraper получает это задание, он будет получать URL-адреса топ-10 результатов для "футбола", фильтруя каждую дату между "start" и "end". То есть топ-10 для "2020-01-01", топ-10 для "2020-01-02"... Я использую пакет "googlesearch", который очень удобен.

Flask-приложение

Для сервера определены три маршрута:

  • /start : вызывается мастером в самом начале. Он создает дочерний процесс Scraper, который работает в фоновом режиме.
  • /job : передает задания от мастера к слейву с параметрами, закодированными в URL.
  • /state : сообщает мастеру текущее состояние слейва (“простаивает”, “занят” или “обнаружено парсинг”).

Создание Мастера

Основным методом в классе Master (нет никакой игры слов) является orchestrate(), который периодически проверяет состояние слейва с помощью check_slave_state и отправляет задание, если он свободен.

Если состояние равно обнаружен парсинг, то вызывается restart_machine() и приложение развертывается. Мастер отслеживает задание, которое вызвало сбой, и повторно отправляет его слейву, как только он снова работает.

Если слейв перестает отвечать (нет ответа), это означает, что он находится в процессе развертывания.

Хорошо, но покажите мне код

Хорошо, вы можете взглянуть на мой репозиторий на GitHub. Чтобы протестировать его локально, вам просто нужно выполнить следующие шаги:

  • pip install -r requirements.txt для установки всех необходимых зависимостей
  • python master.py для запуска мастера
  • gunicorn -b :8080 slave:app --timeout 360000 --preload для запуска слейва (команда, используемая для запуска сервера в Google Cloud)

Не забудьте запустить мастер и слейв из разных сеансов терминала. Пример выполнения мастера выглядит следующим образом:

Развертывание slave на Google Cloud

После того, как вы все протестировали локально, последний шаг - развернуть slave на App Engine из вашего терминала. Сначала вам нужно войти в Google Cloud через командную строку gcloud (выполните gcloud init и выберите свой проект). Затем волшебная команда для развертывания slave...

gcloud app deploy

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

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