Краулер для краулера

в 7:12, , рубрики: docker, python, Анализ и проектирование систем, микросервисы

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

Если интересно, то Добро пожаловать под кат!

Яркими примерами являются задачи копирайтинга, поиск заимствований, утечек документов, в конце концов. Нужен ли для этого свой краулер или можно воспользоваться поисковиками? В ходе решения этого вопроса возникла идея написать “краулер для краулера”, другими словами, сбор данных с поисковиков по заданному запросу.

Первый резонный вопрос: почему не использовать штатное API поисковика? Если мы используем только один поисковик, то можно и API, но для этого надо будет следить за его изменениями и править свой код. Мы же решили сделать универсальный механизм: заменив XPath в настройках, можно настроиться на работу с любыми поисковыми системами (но не ограничиваться ими). Разумеется, пришлось предусмотреть работу со списком прокси, чтобы, во-первых, не забанили, а, во-вторых, чтобы можно было получать поисковую выдачу для разных регионов (по geoIP используемого прокси).

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

Краулер для краулера - 2

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

requests.post('http://127.0.0.1:5000/social', json={
   "jsonrpc":"2.0",
   'id':123,
   'method':'initialize',
   'params':{
      'settings':{
         'searcher':'<твой любимый поисковик>',
         'search_q':[
            'why people hate php'
         ],
         'count':1
      }
   }
})

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

Для чего же нам использовать ту злосчастную эмуляцию, а не использовать всеми любимый requests? Ответ прост:

  • для решения проблемы с динамически подгружаемым контентом;
  • притворяться ужом (пользователем с реальным браузером) для отсрочки блокировки прокси.

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

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

Как только желаемая страница нами получена, дело остается за малым и его с радостью выполнит parser (с использованием сконструированного нами конфига, содержащего Xpath необходимых элементов), который, в свою очередь, отправит интересующую нас информацию в MongoDB.
На каждом этапе выполнения в Redis указывается статус обработки задачи, основываясь на ее id.

Рассмотрим возможные проблемы, с которыми мы можем столкнуться:

  1. Реклама в выдаче — зашумляет данные, раздувает базу;
  2. Сайты могут подгружать контент динамически, например, при прокручивании страницы;
  3. Капча — ну здесь всё очевидно.

Если же сайт маскирует рекламу среди полезного контента, то нам на помощь приходит firefox webdriver + adblock + selenium. Однако, в случае поисковиков, реклама достаточно просто выявляется при помощи XPATH и убирается из выдачи.

Итак, капча — наш злейший враг.
Распознавать её — задача нетривиальная и требует значительных ресурсов для реализации. Значит будем искать путь обхода.

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

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

Также можно использовать антикапча сервис, но это уже совсем другая история…

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

Автор: Михаил

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js