关于scrapy分布式爬虫请求去重和指纹过期的两种方法——思路

本文探讨了Scrapy分布式爬虫在处理请求去重时,如何实现指纹过期的两种策略:1. 使用Redis散列表保存指纹及其过期时间;2. 使用按时间排列的多个Bloomfilter。通过分析优缺点,指出两种方法适用于不同的场景,并提供了思路,但未提供完整实现代码。
摘要由CSDN通过智能技术生成

2019.2.23 更新:

其实第一种方法,在写完这篇博文后没几天我就给实现了。本来想过几天就专门写一篇博文对实现方法、代码作介绍的,但我懒啊,就一直拖到现在还没写。。。先把实现的地址放上吧,相关博文有空了再说(一般来说,有空了再搞 等于 不搞了?=。=)。

项目 github:scrapy_redis_expiredupefilter

地址:https://github.com/AaronJny/scrapy_redis_expiredupefilter

emmm,名字起得有点low。毕竟起名苦手= =!


PS:这篇博文主要讨论思路、方法,有细节伪代码,但没有完整实现代码。如果有时间,后面会专门写一篇实现的博文,附上完整代码。

转载请注明出处:https://blog.csdn.net/aaronjny/article/details/84899262


scrapy应该算是当下最流行、也最受欢迎的python爬虫框架了。利用scrapy,爬虫工程师可以快速开发高效的爬虫程序。

scrapy默认是单机模式,但可以借助scrapy_redis,通过简单的配置,实现单机scrapy程序到分布式爬虫程序的转化。其内在原理可以简单理解为:借助公用的redis数据库,实现请求队列和去重集合的共享,进而使各主机上分布式部署的爬虫程序协调工作。

这里就不深入讨论了,网上相关的资料有很多,这也不是本文讨论的重点,不再多做赘述。

当分布式爬虫开发完成后,有一个问题就被摆在我们面前:如何让请求指纹在指定时间后自动过期?

如果不是很理解这个问题的话,我们举个例子。

假设,我们接到一个需求,需要采集某网站的博文信息。具体的需求是这样的:

  • 1.网站有一个博文列表的入口,可以翻页,我们的爬虫定时运行,每次采集前30页的数据。需要注意的是,这个列表的排序不是按照发布时间排列的,并且博文的更新或者点赞等其他操作都有可能使博文的排序提升
  • 2.一个博文在一个月内只采集一次,当月再次遇到它时不会二次采集,一个月后再碰到会进行采集

在scrapy中,当一个请求被spider发起时,它会先经过去重器校验,校验的过程大致如下:

  • 1.对发起的请求的相关信息,通过特定的算法,生成一个请求指纹
  • 2.判断这个指纹是否存在于指纹集合中
  • 3.如果在指纹集合,则表示此请求曾经执行过,舍弃它
  • 4.如果不在,则表示此为第一次执行,将指纹加入到指纹集合中,并将请求加入到请求队列中,等待调度

我们可以在scrapy中找到对应源码,我加上了注释:

def request_seen(self, request):
        # 计算request的指纹
        fp = self.request_fingerprint(request)
        # 判断指纹是否已经存在
        if fp in self.fingerprints:
            # 已存在
            return True
        # 不存在,加入到指纹集合中
        self.fingerprints.add(fp)

但scrapy的去重集合是单机的,所以scrapy_redis为了实现分布式,重写了去重器,这是其中一部分代码:

def request_seen(self, request):
        """Returns True if request was already seen.
        Parameters
        ----------
        request : scrapy.http.Request
        Returns
  
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值