Scrapy Python 爬虫 框架Scrapy

scrapy源码阅读笔记(2) -- scheduler

2016-12-17  本文已影响540人  troy_ld

数据流向

关于Scheduler

Scheduler主要负责scrapy请求队列的管理,即进队与出队。进一步来说,会涉及到队列的选择,队列去重,序列化。

属性/方法 功能 描述
df 去重模块 默认利用set在内存去重
dqdir 磁盘队列路径 持久化队列至硬盘
pqclass 带优先级队列 默认来自queuelib
dqclass 磁盘队列 持久化队列至硬盘
mqclass 内存队列 默认来自queuelib
stats 状态记录 状态记录通用模块
from_crawler 实例化入口 scrapy风格的实例化入口
has_pending_requests 检查队列数 指向len
open 初始化队列 scrapy模块的初始化入口
close 安全退出接口 scrapy模块的安全入口
enqueue_request 进队api 调度进队
next_request 出队api 调度出队

另外,enqueue_request next_request 封装了一些内部函数,指向queue。

去重 scrapy.dupefilters.RFPDupeFilter

class RFPDupeFilter(BaseDupeFilter):

    def request_seen(self, request):
        fp = self.request_fingerprint(request)
        if fp in self.fingerprints:
            return True
        self.fingerprints.add(fp)
        if self.file:
            self.file.write(fp + os.linesep)

    def request_fingerprint(self, request):
        return request_fingerprint(request)

scrapy默认去重方案:

request_fingerprint默认采用的hashlib.sha1,利用headers/method/url/body生成

队列 queuelib

包含了一些基本的队列FIFO/LIFO, 以及带有优先级的PriorityQueue。Github 上有功能用法介绍

爬取策略

针对不同的场景可能会选择不同的队列。

值得一提的是,在网站数目较多的时候(200~500)个, 这些策略的稳定性都不是很好,(控制单个域名访问频率)亲测都有一定概率遭遇队列阻塞。刚开始下载量可以到1200 page/min, 渐渐降低到300~500, 谈不上慢,但总有些损耗。

域名队列

为了解决域名阻塞的问题,chamilto设计了域名队列去改进, 基本思路

代码实现上,需要修改schduler初始化参数,重载进队出队相关的内部函数。对于内存队列, 性能不是问题, 对于持久化队列(硬盘/数据库)IO压力会增大

序列化

在做队列(对象)持久化/传输时会用到.常见的方案如下

对于scrapy的disk queue来说

scrapy.utils.reqser.request_to_dict 将request转成dict
scrapy.squeues.PickleFifoDiskQueue 做序列化队列

上一篇 下一篇

猜你喜欢

热点阅读