Is there a way to get Scrapy to execute code once the crawl has completely finished to deal with moving / cleaning the data? Am sure it is trivial but my Google-fu seems to have left me for this issue.
2 回答
这完全取决于你如何启动 Scrapy。
crawl
如果使用or从命令行运行runspider
,只需等待该过程完成。请注意,退出代码为 0并不意味着您已成功抓取所有内容。
如果用作库CrawlerProcess.start()
,您可以在调用后附加代码。
如果您需要可靠地跟踪状态,首先您要做的是跟踪spider_closed
信号并检查其reason
参数。页面开头有一个示例,它希望您修改蜘蛛的代码。
要跟踪您添加的所有蜘蛛,当用作库时:
process = CrawlerProcess({})
process.crawl(MySpider)
def spider_ended(spider, reason):
print('Spider ended:', spider.name, reason)
for crawler in process.crawlers:
crawler.signals.connect(spider_ended, signal=scrapy.signals.spider_closed)
process.start()
检查reason
,如果不是'finished'
,则有东西中断了爬虫。
将为每个蜘蛛调用该函数,因此如果您有很多,它可能需要一些复杂的错误处理。还要记住,在收到两次键盘中断后,Scrapy 会开始非正常关闭,并且不会调用该函数,但放置在后面的代码process.start()
无论如何都会运行。
或者,您可以使用扩展机制连接到这些信号,而不会弄乱代码库的其余部分。示例扩展显示如何跟踪此信号。
但这一切只是为了检测因中断而发生的故障。您还需要订阅spider_error
在蜘蛛中出现 Python 异常时将调用的信号。还有必须完成的网络错误处理,请参阅这个问题。
最后,我放弃了跟踪失败的想法,只是使用process.start()
返回后检查的全局变量来跟踪成功。就我而言,成功的时刻是没有找到“下一页”链接。但我有一个线性刮刀,所以很容易,你的情况可能不同。
您可以编写一个捕获spider_close信号的扩展,它将执行您的自定义代码。