Scrapy对接BloomFilter
- 通过修改源码的方式对接
- 对接的原则
- 实现Bloom Filter时,首先要保证不能破坏Scrapy-Redis分布式爬取的运行架构。
- 我们需要修改Scrapy-Redis的源码,将它的去重类替换掉。同时,Bloom Filter的实现需要借助于一个位数组,既然当前架构还是依赖于Redis,那么位数组的维护直接使用Redis就好了。
- 首先实现一个基本的散列算法,将一个值经过散列运算后映射到一个m位数组的某一位上,代码如下:
- 实现BloomFilter过滤器类
- 接下来继续修改Scrapy-Redis的源码
- 修改源码的位置
- 将scrapy-redis的dupefilter逻辑替换为Bloom Filter的逻辑。
- 主要是修改RFPDupeFilter类的request_seen()方法
- 利用request_fingerprint()方法获取Request的指纹,调用Bloom Filter的exists()方法判定该指纹是否存在。如果存在,则说明该Request是重复的,返回True,否则调用Bloom Filter的insert()方法将该指纹添加并返回False。这样就成功利用Bloom Filter替换了Scrapy-Redis的集合去重。
- 修改request_seen方法,修改判断元素是否重复的方法
- 修改__init__ 方法,将判断重复类修改为BloomFilter
- 相关参数,通过from_setting方法获取
- 修改setting文件
- BLOOMFILTER_HASH_NUMBER = 6 配置布隆过滤器的哈希函数的数量
- BLOOMFILTER_BIT = 30 设置存储使用的位数
- 直接使用scrapy-redis-bloomfilter框架
- 下载scrapy-redis-bloomfilter
- pip3 install scrapy-redis-bloomfilter
- 修改setting.py文件
- DUPEFILTER_CLASS = "scrapy_redis_bloomfilter.dupefilter.RFPDupeFilter" # 去重类,要使用Bloom Filter请替换DUPEFILTER_CLASS
- BLOOMFILTER_HASH_NUMBER = 6 # 散列函数的个数,默认为6,可以自行修改
- BLOOMFILTER_BIT = 30 # Bloom Filter的bit位移参数(代表 1 << 30 ),默认30,占用128MB空间,去重量级1亿