作业:暂停和恢复抓取

有时,对于大型网站,暂停抓取并能够在以后恢复它们是可取的。

Scrapy 通过提供以下功能,开箱即用地支持此功能

  • 一个将待抓取请求持久化到磁盘的调度器

  • 一个将已访问请求持久化到磁盘的去重过滤器

  • 一个在批次之间保持一些爬虫状态 (键值对) 持久化的扩展

作业目录

要启用持久性支持,您只需通过 JOBDIR 设置定义一个 *作业目录*。此目录用于存储所有必需的数据,以保持单个作业 (即一次爬虫运行) 的状态。重要的是要注意,此目录不得由不同的爬虫共享,甚至同一个爬虫的不同作业/运行也不得共享,因为它旨在用于存储 *单个* 作业的状态。

如何使用

要启动一个启用了持久性支持的爬虫,运行命令如下

scrapy crawl somespider -s JOBDIR=crawls/somespider-1

然后,您可以在任何时候安全地停止爬虫 (通过按 Ctrl-C 或发送信号),并在以后通过发出相同的命令来恢复它。

scrapy crawl somespider -s JOBDIR=crawls/somespider-1

在批次之间保持持久状态

有时您会希望在暂停/恢复批次之间保持一些持久的爬虫状态。您可以使用 spider.state 属性来实现此目的,它应该是一个 dict。有一个 内置扩展 负责在爬虫启动和停止时,从作业目录序列化、存储和加载该属性。

以下是一个使用爬虫状态的回调示例 (为简洁起见,省略了其他爬虫代码)

def parse_item(self, response):
    # parse item here
    self.state["items_count"] = self.state.get("items_count", 0) + 1

持久化注意事项

如果您想使用 Scrapy 的持久性支持,有一些事情需要记住

Cookies 过期

Cookies 可能会过期。因此,如果您不快速恢复爬虫,调度好的请求可能不再有效。如果您的爬虫不依赖于 cookies,这将不是问题。

Request 序列化

为了使持久性工作,Request 对象必须能够使用 pickle 进行序列化,除了传递给它们的 __init__ 方法的 callbackerrback 值,它们必须是正在运行的 Spider 类的方法。

如果您希望记录无法序列化的请求,您可以在项目的设置页面中将 SCHEDULER_DEBUG 设置为 True。它默认是 False