ReactorNotRestartable ошибка во время цикла с помощью scrapy

Я получаю ошибку twisted.internet.error.ReactorNotRestartable при выполнении следующего кода:

from time import sleep
from scrapy import signals
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy.xlib.pydispatch import dispatcher

result = None

def set_result(item):
    result = item

while True:
    process = CrawlerProcess(get_project_settings())
    dispatcher.connect(set_result, signals.item_scraped)

    process.crawl('my_spider')
    process.start()

    if result:
        break
    sleep(3)

В первый раз, когда он работает, я получаю сообщение об ошибке. Я создаю переменную process каждый раз, так что проблема?

Ответ 1

По умолчанию CrawlerProcess .start() останавливает Twisted реактор, который он создает, когда все сканеры завершают работу.

Вы должны вызвать process.start(stop_after_crawl=False) если вы создаете process в каждой итерации.

Другой вариант - это самостоятельно управлять реактором Twisted и использовать CrawlerRunner. В документах есть пример для этого.

Ответ 2

Я смог решить эту проблему следующим образом. process.start() должен вызываться только один раз.

from time import sleep
from scrapy import signals
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy.xlib.pydispatch import dispatcher

result = None

def set_result(item):
    result = item

while True:
    process = CrawlerProcess(get_project_settings())
    dispatcher.connect(set_result, signals.item_scraped)

    process.crawl('my_spider')

process.start()

Ответ 3

Ссылка http://crawl.blog/scrapy-loop/

 import scrapy
 from scrapy.crawler import CrawlerProcess
 from scrapy.utils.project import get_project_settings     
 from twisted.internet import reactor
 from twisted.internet.task import deferLater

 def sleep(self, *args, seconds):
    """Non blocking sleep callback"""
    return deferLater(reactor, seconds, lambda: None)

 process = CrawlerProcess(get_project_settings())

 def _crawl(result, spider):
    deferred = process.crawl(spider)
    deferred.addCallback(lambda results: print('waiting 100 seconds before 
    restart...'))
    deferred.addCallback(sleep, seconds=100)
    deferred.addCallback(_crawl, spider)
    return deferred


_crawl(None, MySpider)
process.start()