1. 一般经常用的通用思路:
将爬取的url保存到数据库中,当获取下一个url的时候,就去数据库中查询这个url是否已经被访问过了。虽然数据库有缓存,但是当每个url读取数据库中查询的话,会导致效率下降的很快,所以这种策略用的不多,但是是最简单的一种方法。
2. 将访问过的url保存到set中去
通过这种方式获取url的速度会很快,基本上不用做查询。但是这种方法有一个缺点,将url保存到set中,实际上是保存在内存中,当url数据量很大的时候,会导致内存的压力越来越大。对于小型的爬虫来说,这个方法十分的可取,但是对于大型的网络爬虫,这种方法就难以企及了。
3. 将字符进行MD5编码
MD5编码可以将字符缩减到固定的长度。一般来说,MD5编码长度约为128bit,约等于16byte。在未缩减之前,假设一个url占用的内存大小为50个字节,一个字节等于2byte,相当于100byte。由此可见,进行MD5编码之后,节约了大量的内存空间。通过MD5可以将任意长度的url压缩到同样长度的MD5字符串,而且不会出现重复的情况,达到去重的效果。通过这种方式很大程度上节约了内存,scrapy框架采取的方式同MD5 方式有些类似。所以所scrapy在正常情况下,既是url的数量级达到了上亿级别,其占用的内存比起set方式也要少的多。
4. 使用bitmap方法将字符进一步压缩
这种方式的意思是在计算机中申请8个bit,即8个位,每个位由0或1表示,一个位代表一个url的话,为什么一个位可以确定一个url呢?因为我们可以将一个url进行一个哈希函数,然后映射到其位上面去。举个例子,假设我们有8个url,分别对应8个位,然后通过位上面的0或1状态,便可以表明这个url是否存在,通过这种方法便可以进一步的压缩内存。
但是这种方法有一个非常大的缺点,就是他的冲突会非常高,因为同用一个哈希函数,极有可能将两个不同的url或者多个不同的url映射到一个位置上来。实际上这种哈希的方法,他也是set方式的一种实现原理,他讲url进行一种函数计算,然后映射到bit的位置中去,所以这种方式对内存的压缩是非常大的。
简单的来计算一下,还是以一亿条url来进行计算,相当于一亿个bit,通过计算得到其相当于12500000byte,除以1024之后约为12207KB,大概是12MB的空间。在实际过程中内存的占用可能会比12MB大一些,但是即便如此,相比于前面三种方法,这种方式已经大大的减少了内存占用的空间了。
但是与此同时,该方法产生冲突的可能性是非常大的,所以这种方式也不是太实用的。那么有没有方法将这种内存浓重压缩的方法做进一步的优化,让冲突的可能性将下来呢?答案就是第五中方式
5. bloomfilter,该方法对bitmap进行改进
他可以通过多个哈希函数减少冲突的可能性。通过这种方式,一方面它既可以达到bitmap方法减少内存的作用,另一方面他又同事起到减少冲突的作用。
具体的后续补充