几种去重策略对比
1)使用scrapy自带的set集合去重,当程序结束的时候会被清空,缺点:再次运行会导致数据重复。
2)使用mysql做去重,对url地址进行md5,base64加密,加密之后会得到一串字符,判断字符串
是否在mysql表中,如果在表示已经爬取过了,如果不在,表示没有爬取,执行请求,将加密后的url
地址存入表中。缺点: 但是这个方法对mysql压力过大,数据量太大容易导致崩溃,不推荐
3)使用scrapy_redis的去重策略,会将已经爬取的url地址经过编码后存入redis,并且会做数据持久化,
当爬虫再次启动时,会重新加载本地的数据,对爬虫的url做去重。缺点:如果数据量较大的时候,会占用较多的内存空间
4)使用布隆去重,采用多重哈希,将url地址映射到位阵列中的某个点上,空间和时间利用率更高(推荐)
布隆的原理
布隆过滤器:一种数据结构,是由一串很长的二进制向量组成,可以将其看成一个二进制数组。既然是二进制,那么里面存放的不是0,就是1,但是初始默认值都是0。
如下所示:

①、添加数据
介绍概念的时候,我们说可以将布隆过滤器看成一个容器,那么如何向布隆过滤器中添加一个数据呢?
如下图所示:当要向布隆过滤器中添加一个元素key时,我们通过多个hash函数,算出一个值,然后将这个值所在的方格置为1。
比如,下图hash1(key)=1,那么在第2个格子将0变为1(数组是从0开始计数的),hash2(key)=7,那么将第8个格子置位1,依次类推。

②、判断数据是否存在?
知道了如何向布隆过滤器中添加一个数据,那么新来一个数据,我们如何判断其是否存在于这个布隆过滤器中呢?
很简单,我们只需要将这个新的数据通过上面自定义的几个哈希函数,分别算出各个值,然后看其对应的地方是否都是1,如果存在一个不是1的情况,那么我们可以说,该新数据一定不存在于这个布隆过滤器中。
反过来说,如果通过哈希函数算出来的值,对应的地方都是1,那么我们能够肯定的得出:这个数据一定存在于这个布隆过滤器中吗?
答案是否定的,因为多个不同的数据通过hash函数算出来的结果是会有重复的,所以会存在某个位置是别的数据通过hash函数置为的1。
我们可以得到一个结论:布隆过滤器可以判断某个数据一定不存在,但是无法判断一定存在。
③、布隆过滤器优缺点
优点:优点很明显,二进制组成的数组,占用内存极少,并且插入和查询速度都足够快。
缺点:随着数据的增加,误判率会增加;还有无法判断数据一定存在;另外还有一个重要缺点,无法删除数据。
Redis实现布隆过滤器
redis 实现的方式是采用了Bitmaps
的“数据结构”实现的(本质上还是一个字符串),Bitmaps
已经提供了位操作的接口。
1 设置值
setbit key offset value

我们知道"b"的二进制表示为0110 0010,我们将第7位(从0开始)设置为1,那0110 0011 表示的就是字符“c”,所以最后的字符 “big”变成了“cig”。
网友评论