Scrapy 的断点爬取

Jobs: 暂停,恢复爬虫

有些情况下,例如爬取大的站点,我们希望能暂停爬取,之后再恢复运行。

Scrapy通过如下工具支持这个功能:

一个把调度请求保存在磁盘的调度器
一个把访问请求保存在磁盘的副本过滤器[duplicates filter]
一个能持续保持爬虫状态(键/值对)的扩展

Job 路径:

要启用持久化支持,你只需要通过 JOBDIR 设置 job directory 选项。
这个路径将会存储 所有的请求数据来保持一个单独任务的状态(例如:一次
spider爬取(a spider run))。必须要注意的是,这个目录不允许被不同的
spider 共享,甚至是同一个spider的不同jobs/runs也不行。也就是说,
这个目录就是存储一个 单独 job的状态信息。
怎么使用??? 要启用一个爬虫的持久化,运行以下命令:

scrapy crawl 爬虫名称 -s JOBDIR=crawls/爬虫名称

然后,你就能在任何时候安全地停止爬虫(按Ctrl-C或者发送一个信号,这时候会看到crawls文件夹下保存了一些文件)。恢复这个爬虫也是同样的命令:

scrapy crawl 爬虫名称 -s JOBDIR=crawls/爬虫名称

持久化的一些坑 如果你想要使用 Scrapy 的持久化支持,还有一些东西您需要了解:

注意Cookies 的有效期 Cookies 是有有效期的(可能过期)。所以如果你没有把你的爬虫及时恢复,那么他可能在被调度回去的时候 就不能工作了。当然如果你的爬虫不依赖 cookies 就不会有这个问题了。

请求序列化 请求是由 pickle 进行序列化的,所以你需要确保你的请求是可被 pickle 序列化的。 这里最常见的问题是在在 request 回调函数中使用 lambda 方法,导致无法序列化。

例如,这样就会有问题:

def some_callback(self, response):
    somearg = 'test'
    return scrapy.Request(
        'http://www.example.com', 
        callback= lambda r: self.other_callback(r, somearg)
    )

def other_callback(self, response, somearg):
    print("the argument passed is:", somearg)

这样才对:

def some_callback(self, response):
    somearg = 'test'

    return scrapy.Request(
        'http://www.example.com', 
        meta={'somearg': somearg}, 
        callback=self.other_callback
    )

def other_callback(self, response):
    somearg = response.meta['somearg']
    print("the argument passed is:", somearg)

后面我们会将到scrapy-redis分布式爬虫,可以使用scrapy-redis的相关组件来实现暂停和恢复的操作,我们爬取的相关数据会被存放在redis的数据库中

    原文作者:宁que
    原文地址: https://www.jianshu.com/p/1203b5bf1127
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞