Scrapy 去重
Scrapy 去重
RFPDupeFilter这个类 set()集合
那么在 scrapy 中是如何来使用这个类的方法的呢?什么时候使用,这个流程是怎样的呢?
这个可以追溯到 scrapy.core.scheduler 中定义的 Scheduler 类来决定。
现在就来看看 Scheduler 类中和过滤重复 url 有关的内容。
在 Scheduler 类中,在调度时,采用了 memory queue 和 disk queue 的存储方法,所以,有一个入队的方法,在入队前,就要对 request
进行检查,检查是否是重复,如果已经重复了,就不入队了。
这里两个条件控制,首先是配置中 dont_filter,如果它是 True,就说明是不筛选的,如果是 False,才是要筛选的。后面的 request_seen() 在默认内置的筛选方法中,就是 RFPDupeFilter() 中的方法,检查 request 是否已经存在。
只有要筛选且没有见过这个 request,才会去筛选 url。
所以这里已经很清晰了,调度器收到了 enqueue_request()
调用时,会检查这个 url 重复的判断开关,如果要筛选,就要检查这个 request 是否已经存在了;这里的检查 if 如果成立,就直接返回了,只有不成立时,才会有后续的存储操作,也就是入队.
下面来看看 scrapy 中是如何判断两个 url 重复的。
关键的函数是 request_fingerprint
,这个是判断是否重复的关键实现方(scrapy.utils.request.request_fingerprint()
)。
默认的调用情况下,计算的内容包括 method、格式化后的 url、请求正文,还有就是 http headers 是可选的。
和通常情况下不一样的是,这里的计算指纹,不是单纯的比较了 url 是否一致。计算的结果是一串 hash 16 进制数字