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()