Широкие обходы

Значения по умолчанию Scrapy оптимизированы для сканирования определённых сайтов. Данные сайты часто обрабатываются одним пауком Scrapy, хотя это не является обязательным или обязательным (например, существуют общие пауки, которые обрабатывают любой данный сайт, переданный им).

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

Это некоторые общие свойства, часто встречающиеся при широких обходах:

  • они сканируют множество доменов (часто неограниченных) вместо определенного набора сайтов

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

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

  • они сканируют множество доменов одновременно, что позволяет им достигать более высоких скоростей сканирования, не будучи ограниченными какими-либо конкретными ограничениями сайта (каждый сайт сканируется медленно, чтобы соблюсти вежливость, но многие сайты сканируются параллельно)

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

Используйте правый SCHEDULER_PRIORITY_QUEUE

Очередь приоритета планировщика Scrapy по умолчанию — 'scrapy.pqueues.ScrapyPriorityQueue'. Лучше всего он работает при сканировании одного домена. Это не очень хорошо работает при параллельном сканировании множества разных доменов

Для применения рекомендованного приоритета используйте очередь:

SCHEDULER_PRIORITY_QUEUE = 'scrapy.pqueues.DownloaderAwarePriorityQueue'

Увеличьте конкурентность

Конкурентность — это количество запросов, которые обрабатываются параллельно. Существует глобальный лимит (CONCURRENT_REQUESTS) и дополнительный лимит, который можно установить либо для домена (CONCURRENT_REQUESTS_PER_DOMAIN), либо для IP (CONCURRENT_REQUESTS_PER_IP).

Примечание

Очередь приоритетов планировщика, рекомендуемая для широкого обхода, не поддерживает CONCURRENT_REQUESTS_PER_IP.

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

Хорошая отправная точка — 100:

CONCURRENT_REQUESTS = 100

Но лучший способ выяснить это — провести несколько проб и определить, при каком параллелизме ваш процесс Scrapy ограничивает ЦП. Для оптимальной производительности вы должны выбрать параллелизм, при котором загрузка ЦП составляет 80-90%.

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

Увеличивает максимальный размер пула потоков Twisted IO

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

Чтобы увеличить максимальный размер пула потоков, используйте:

REACTOR_THREADPOOL_MAXSIZE = 20

Настраивает свой собственный DNS

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

Уменьшите уровень журналирования

При выполнении широкого сканирования вас часто интересуют только получаемые вами скорости сканирования и любые обнаруженные ошибки. Эта статистика сообщается Scrapy при использовании уровня журнала INFO. В целях экономии ресурсов ЦП (и требований к хранилищу журналов) не следует использовать уровень журнала DEBUG при предварительном формировании больших широких обходов в рабочей среде. Тем не менее, использование уровня DEBUG при разработке вашего (широкого) поискового робота может быть приемлемым.

Чтобы установить уровень журнала, используйте:

LOG_LEVEL = 'INFO'

Отключить куки

Отключите cookie, если действительно они вам не нужны. Cookie часто не нужны при широком сканировании (сканеры поисковых систем игнорируют их), и они повышают производительность за счёт экономии некоторых циклов процессора и уменьшения объёма памяти, занимаемой вашим сканером Scrapy.

Чтобы отключить использование cookie:

COOKIES_ENABLED = False

Отключить повторные попытки

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

Чтобы отключить повторные попытки, используйте:

RETRY_ENABLED = False

Уменьшает время ожидания загрузки

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

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

DOWNLOAD_TIMEOUT = 15

Отключите перенаправления

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

Для отключения перенаправления используйте:

REDIRECT_ENABLED = False

Включите сканирование «страниц для сканирования Ajax»

Некоторые страницы (до 1%, по эмпирическим данным за 2013 год) объявляют себя как ajax сканируемые. Это означает, что они предоставляют простую HTML-версию контента, которая обычно доступна только через AJAX. Страницы могут указывать на это двумя способами:

  1. используйте #! в URL-адресе — это способ по умолчанию;

  2. с помощью специального метатега — так используется на «основных», «индексных» страницах сайта.

Scrapy обрабатывает (1) автоматически; для настройки (2) включите AjaxCrawlMiddleware:

AJAXCRAWL_ENABLED = True

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

Сканирование в порядке BFO

Scrapy сканирует в порядке DFO по умолчанию.

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

Сканирование в порядке BFO вместо этого для экономии памяти.

Помните об утечках памяти

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

Устанавливает конкретный Twisted реактор

Если сканирование превышает возможности системы, вы можете попробовать установить конкретный Twisted реактор с помощью параметра TWISTED_REACTOR.