所以,我创建了这个类,这样我就可以使用Scrapy按需爬行:
from scrapy import signals
from scrapy.crawler import CrawlerProcess, Crawler
from scrapy.settings import Settings
class NewsCrawler(object):
def __init__(self, spiders=[]):
self.spiders = spiders
self.settings = Settings()
def crawl(self, start_date, end_date):
crawled_items = []
def add_item(item):
crawled_items.append(item)
process = CrawlerProcess(self.settings)
for spider in self.spiders:
crawler = Crawler(spider, self.settings)
crawler.signals.connect(add_item, signals.item_scraped)
process.crawl(crawler, start_date=start_date, end_date=end_date)
process.start()
return crawled_items
基本上,我有一个长时间运行的进程,我将多次调用上述类的crawl
方法,如下所示:
import time
crawler = NewsCrawler(spiders=[Spider1, Spider2])
while True:
items = crawler.crawl(start_date, end_date)
# do something with crawled items ...
time.sleep(3600)
问题是,第二次调用crawl
时,将出现以下错误:twisted.internet.error.ReactorNotRestartable
.
据我所知,这是因为React堆在停止运行后无法运行。有什么解决办法吗?
谢谢你!
2条答案
按热度按时间inkz8wg91#
这是目前Scrapy(扭曲)的一个限制,使它很难使用Scrapy作为一个lib。
你可以做的是派生一个新的进程,它运行爬行器,并在爬行完成后停止React器。然后你可以等待加入,并在爬行完成后产生一个新的进程。如果你想在主线程中处理项目,你可以将结果发布到队列中。我建议你为项目使用自定义的管道。
看一下下面由我回答:https://stackoverflow.com/a/22202877/2208253
你应该能够应用同样的原理。但是你宁愿使用多处理而不是台球。
5ssjco0h2#
根据@bj-blazkowicz的回答,我找到了一个解决方案,它是运行多个蜘蛛时推荐使用的爬虫,如文档www.example.com中所述https://docs.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script
还有另一个Scrapy实用程序,它提供了对爬行过程的更多控制:scrapy.crawler.CrawlerRunner.这个类是一个简单的 Package 器,它封装了一些简单的帮助器来运行多个爬虫程序,但是它不会以任何方式启动或干扰现有的React器。
使用这个类,React器应该在调度蜘蛛后显式运行。如果你的应用程序已经在使用Twisted,并且你想在同一个React器中运行Scrapy,建议你使用CrawlerRunner而不是CrawlerProcess。
主文件中的代码:
您的spider文件中的代码: