Выполнение заданий Scrapy в Python - PullRequest
10 голосов
/ 03 ноября 2011

Мой скрипт Scrapy работает нормально, когда я запускаю его в сценариях «один раз» из командной строки, но если я пытаюсь запустить код дважды в одном сеансе Python, я получаю эту ошибку:

"ReactorNotRestartable"

Почему?

Код обидчика (последняя строка выдает ошибку):

crawler = CrawlerProcess(settings)
crawler.install()
crawler.configure()

# schedule spider
#crawler.crawl(MySpider())
spider = MySpider()
crawler.queue.append_spider(spider)

# start engine scrapy/twisted
crawler.start()

Ответы [ 4 ]

11 голосов
/ 03 ноября 2011

Близко к ответу Жоэля, но я хочу уточнить немного больше, чем это возможно в комментариях.Если вы посмотрите на исходный код Crawler , вы увидите, что класс CrawlerProcess имеет функцию start, а также функцию stop.Эта функция stop заботится о том, чтобы очистить внутреннюю часть сканирования, чтобы система оказалась в состоянии, из которого она может начать снова.

Итак, если вы хотите возобновить сканирование, не выходя из процессаПозвоните crawler.stop() в соответствующее время.Позже, просто позвоните crawler.start() снова, чтобы возобновить операции.

Edit: в ретроспективе, это невозможно (из-за закрученного реактора, как упомянуто в другом ответе);stop просто заботится о чистом окончании.Оглядываясь назад, я обнаружил, что у меня есть оболочка для процессов Crawler.Ниже вы можете найти некоторый (отредактированный) код, чтобы заставить его работать, используя многопроцессорный модуль Python.Таким образом, вы можете легче перезапустить сканеры.(Примечание: я нашел код в сети в прошлом месяце, но я не включил источник ... поэтому, если кто-то знает, откуда он взялся, я обновлю ссылки на источник.)

from scrapy import project, signals
from scrapy.conf import settings
from scrapy.crawler import CrawlerProcess
from scrapy.xlib.pydispatch import dispatcher
from multiprocessing.queues import Queue
from multiprocessing import Process

class CrawlerWorker(Process):
    def __init__(self, spider, results):
        Process.__init__(self)
        self.results = results

        self.crawler = CrawlerProcess(settings)
        if not hasattr(project, 'crawler'):
            self.crawler.install()
        self.crawler.configure()

        self.items = []
        self.spider = spider
        dispatcher.connect(self._item_passed, signals.item_passed)

    def _item_passed(self, item):
        self.items.append(item)

    def run(self):
        self.crawler.crawl(self.spider)
        self.crawler.start()
        self.crawler.stop()
        self.results.put(self.items)

# The part below can be called as often as you want
results = Queue()
crawler = CrawlerWorker(MySpider(myArgs), results)
crawler.start()
for item in results.get():
    pass # Do something with item
2 голосов
/ 03 ноября 2011

crawler.start() запускает витой реактор.Может быть только один реактор.

Если вы хотите запустить больше пауков - используйте

another_spider = MyAnotherSpider()
crawler.queue.append_spider(another_spider)
0 голосов
/ 24 марта 2016

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

Thread (target = process.start) .start ()

Вот подробное объяснение: Запустите паука Scrapy в задаче Celery

0 голосов
/ 03 ноября 2011

Мне кажется, что вы не можете использовать команду crawler.start() дважды: возможно, вам придется пересоздать ее, если вы хотите, чтобы она запускалась во второй раз.

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