Scrapy 去重源码分析
Scrapy 去重源码分析
# 去重源码分析 # from scrapy.core.scheduler import Scheduler # Scheduler下:def enqueue_request(self, request)方法判断是否去重 if not request.dont_filter and self.df.request_seen(request): Requests对象,RFPDupeFilter对象 # 如果要自己写一个去重类 -写一个类,继承BaseDupeFilter类 -重写def request_seen(self, request): -在setting中配置:DUPEFILTER_CLASS = '项目名.dup.UrlFilter' -增量爬取(100链接,150个链接) -已经爬过的,放到某个位置(mysql,redis中:集合) -如果用默认的,爬过的地址,放在内存中,只要项目一重启,就没了,它也不知道我爬过那个了,所以要自己重写去重方案 -你写的去重方案,占得内存空间更小 -bitmap方案 -BloomFilter布隆过滤器 from scrapy.http import Request from scrapy.utils.request import request_fingerprint # 这种网址是一个 requests1=Request(url='https://www.baidu.com?name=lqz&age=19') requests2=Request(url='https://www.baidu.com?age=18&name=lqz') ret1=request_fingerprint(requests1) ret2=request_fingerprint(requests2) print(ret1) print(ret2) # bitmap去重 一个小格表示一个连接地址 32个连接,一个比特位来存一个地址 # https://www.baidu.com?age=18&name=lqz ---》44 # https://www.baidu.com?age=19&name=lqz ---》89 # c2c73dfccf73bf175b903c82b06a31bc7831b545假设它占4个bytes,4*8=32个比特位 # 存一个地址,占32个比特位 # 10个地址,占320个比特位 #计算机计量单位 # 比特位:只能存0和1 def request_seen(self, request): # 把request对象传入request_fingerprint得到一个值:aefasdfeasd # 把request对象,唯一生成一个字符串 fp = self.request_fingerprint(request) #判断fp,是否在集合中,在集合中,表示已经爬过,return True,他就不会再爬了 if fp in self.fingerprints: return True # 如果不在集合中,放到集合中 self.fingerprints.add(fp) if self.file: self.file.write(fp + os.linesep)