作业:暂停和恢复爬取
有时,对于大型网站,需要暂停爬取并在以后能够恢复它们。
Scrapy 通过提供以下功能,开箱即用地支持此功能
一个将计划请求持久化到磁盘的调度器
一个将已访问请求持久化到磁盘的去重过滤器
一个扩展,用于在批次之间保持某些爬虫状态(键/值对)的持久性
作业目录
要启用持久化支持,请通过 JOBDIR 设置定义一个 作业目录。
作业目录将存储所有必需的数据,以保持 单个 作业(即一次爬虫运行)的状态,以便如果干净地停止,以后可以恢复。
警告
此目录 不 能被不同的爬虫共享,甚至不能被同一爬虫的不同作业共享。
警告
对待作业目录应与对待 Scrapy 项目源代码一样谨慎。不要将 JOBDIR 指向不受信任方可写入的路径。
另请参阅 作业目录内容。
如何使用
要启动一个启用持久化支持的爬虫,请像这样运行它
scrapy crawl somespider -s JOBDIR=crawls/somespider-1
然后,您可以随时安全地停止爬虫(通过按下 Ctrl-C 或发送信号),并在以后通过发出相同的命令来恢复它
scrapy crawl somespider -s JOBDIR=crawls/somespider-1
在批次之间保持持久状态
有时您需要在暂停/恢复批次之间保留一些持久的爬虫状态。您可以使用 spider.state 属性,它应该是一个字典。有一个 内置扩展,负责在爬虫启动和停止时,将该属性从作业目录序列化、存储和加载。
这是一个使用爬虫状态的回调示例(为简洁起见,省略了其他爬虫代码)
def parse_item(self, response):
# parse item here
self.state["items_count"] = self.state.get("items_count", 0) + 1
持久化注意事项
如果您想使用 Scrapy 的持久化支持,有几点需要记住
暂停限制
作业的暂停和恢复仅在爬虫干净停止时才受支持。强制、突然或以其他方式不干净的关闭可能导致作业目录中的数据损坏,这可能会阻止爬虫正确恢复。
请求序列化
为了使持久化工作,Request 对象必须可以通过 pickle 进行序列化,但传递给其 __init__ 方法的 callback 和 errback 值除外,它们必须是正在运行的 Spider 类的方法。
如果您希望记录无法序列化的请求,可以将项目设置页面中的 SCHEDULER_DEBUG 设置设为 True。默认情况下,它为 False。
作业目录内容
作业目录的内容取决于作业期间使用的组件。已知会写入作业目录的组件包括 调度器 和 SpiderState 扩展。有关详细信息,请参阅相应组件的参考文档。
例如,在默认设置下,作业目录可能如下所示
├── requests.queue
| ├── active.json
| └── {hostname}-{hash}
| └── {priority}{s?}
| ├── q{00000}
| └── info.json
├── requests.seen
└── spider.state
其中
Scheduler创建requests.queue/目录和active.json文件,后者包含上次作业暂停时由DownloaderAwarePriorityQueue.close()返回的状态数据。DownloaderAwarePriorityQueue创建{hostname}-{hash}目录。ScrapyPriorityQueue创建{priority}{s?}目录。scrapy.squeues.PickleLifoDiskQueue,一个queuelib.LifoDiskQueue的子类,它使用pickle来序列化scrapy.Request对象的dict表示形式,创建info.json和q{00000}文件。RFPDupeFilter创建requests.seen文件。SpiderState创建spider.state文件。