Scrapy-redis:
requests对象什么时候会入队:
- dont_filter = True,构造请求的时候,把dont_filter置为True,该url会被反复抓取(url对应的内容会更新的情况,比如贴吧这种)
- 一个全新的url被抓到的时候,构造requests请求
- url地址在start_urls中的时候,会入队,不管之前是否被请求过
源码中如下:
1 2 3 4 5 6 |
def enqueue_request(self, request): if not request.dont_fileter and self.df.request_seen(request): self.df.log(request, self.spider) return False self.queue.push(request) return True |
scrapy-redis去重的方法:
- 使用sha1加密request得到指纹
- 把指纹存在redis的集合中
- 下一次新来的request,同样的方式生成指纹,判断指纹是否存在redis的集合中
生成指纹方法如下:
1 2 3 4 5 |
fp = hashlib.sha1() fp.update(to_bytes(request.method)) #请求方法 fp.update(to_bytes(canonicalize_url(request.url))) #url fp.update(request.body or b’’)) #请求体 return fp.hexdigest() |
判断数据是否存在redis的集合中,不存在就插入:
1 2 |
added = self.server.sadd(self.key, fp) Return added != 0 |
Scrapy:
如何去重:
也是通过sha1生成指纹,把指纹和内存中的一个集合进行比较,不存在就添加指纹