Как мне остановить всех пауков и двигатель сразу после того, как условие в трубопроводе выполнено? - PullRequest
12 голосов
/ 14 марта 2012

У нас есть система, написанная со скрэпом, для сканирования нескольких сайтов. Существует несколько пауков и несколько каскадных конвейеров для всех элементов, пропущенных всеми сканерами. Один из компонентов конвейера запрашивает у серверов Google геокодирование адресов . Google накладывает ограничение в 2500 запросов в день на IP-адрес и угрожает заблокировать IP-адрес, если он продолжит запрашивать Google, даже после того, как Google ответит предупреждающим сообщением: «OVER_QUERY_LIMIT».

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

Я проверил другие подобные вопросы, и их ответы не сработали:

from scrapy.project import crawler
crawler._signal_shutdown(9,0) #Run this if the cnxn fails.

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

import sys
sys.exit("SHUT DOWN EVERYTHING!")

этот вообще не работает; элементы продолжают генерироваться и передаваться в конвейер, хотя журнал рвёт sys.exit () -> exceptions.SystemExit поднял (безрезультатно)

crawler.engine.close_spider(self, 'log message')

Эта проблема та же, что и в первом случае, упомянутом выше.

Я пытался:

scrapy.project.crawler.engine.stop()

безрезультатно

EDIT : Если я делаю в конвейере:

из scrapy.contrib.closespider import CloseSpider

что я должен передать в качестве аргумента 'crawler' для CloseSpider init () из области моего конвейера?

1 Ответ

16 голосов
/ 14 марта 2012

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

РЕДАКТИРОВАТЬ : avaleske отмечает в комментариях к этому ответу, что ему удалось вызвать исключение CloseSpider из конвейера.Наиболее разумно было бы использовать это.

Аналогичная ситуация была описана в группе пользователей Scrapy, в этой теме.

Я цитирую:

Чтобы закрыть паук для любой части вашего кода, вы должны использовать метод engine.close_spider.См. Это расширение для примера использования: https://github.com/scrapy/scrapy/blob/master/scrapy/contrib/closespider.py#L61

Вы можете написать свое собственное расширение, хотя в качестве примера рассмотрите closespider.py, которое отключит паука, если будет выполнено определенное условие..

Другим «хаком» будет установка флага на паука в конвейере.Например:

конвейер:

def process_item(self, item, spider):
    if some_flag:
        spider.close_down = True

паук:

def parse(self, response):
    if self.close_down:
        raise CloseSpider(reason='API usage exceeded')
...