scrapy的去重机制
1、scrapy是通过hashlib算法转成长度一致的url,然后再通过set集合去重的,有兴趣看源码
from scrapy.utils.request import request_fingerprint
def request_fingerprint(request, include_headers=None):
fp = hashlib.sha1() # 指纹是hashlib表示来生成一个固定长度的哈兮值
fp.update(to_bytes(request.method))
fp.update(to_bytes(canonicalize_url(request.url)))
fp.update(request.body or b'')
2、在scrapy框架中去重的中间件文件 dupefilters.py文件 :
# 封装去重类 class RFPDupeFilter(BaseDupeFilter): """Request Fingerprint duplicates filter""" def __init__(self, path=None, debug=False): self.file = None self.fingerprints = set() # 去重器 self.logdupes = True #log日志 self.debug = debug #调试 self.logger = logging.getLogger(__name__) #有个函数叫 request_seen() 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) # 被scrapy/core/scheduler.py调用这个是调度器 class Scheduler(object): # enqueue_request()的函数:spider的每来一个url就是通过这个函数来执行的 def enqueue_request(self, request): if not request.dont_filter and self.df.request_seen(request): self.df.log(request, self.spider) return False
每次执行之前都会调用到 request_seen(request) 这个方法
这个方法就会生成一个指纹,指纹下面的掉用的就比较复杂了,简单的说就是要去执行 hashlib.sha1() 这个算法来生成一个固定长度的哈兮值
再然后就是在那个去重器中的
self.fingerprints = set()
就是通过上句代码执行了set集合来去重了