网络爬虫中的去重是非常重要的一步,它能有效减少爬取重复网页的次数,提高爬取效率和质量。下面,我将为大家讲解网络爬虫如何去重的完整攻略。
一、去重原理
理解去重原理是基础,目前流行的去重方法有哈希去重、布隆过滤器去重和数据库去重等多种。其中,布隆过滤器被认为是最为高效的一种去重方法。
布隆过滤器本质上是一个很长的二进制向量和一些随机映射函数。假如需要对一个网址进行去重,则可以将这个网址通过多个不同的哈希函数映射到二进制向量中。如果向量中每个位置都为1,则说明这个网址已经被访问过了;如果向量中至少存在一个位置为0,则说明这个网址没有被访问过。
二、应用示例
1. Python实现布隆过滤器去重
下面是Python实现布隆过滤器去重的基本代码:
import pyhash
import bitarray
class BloomFilter:
def __init__(self, size, hash_func):
self.size = size
self.hash_func = hash_func
self.bit_array = bitarray.bitarray(size)
self.bit_array.setall(0)
def add(self, item):
for hf in self.hash_func:
index = hf(item) % self.size
self.bit_array[index] = 1
def contains(self, item):
for hf in self.hash_func:
index = hf(item) % self.size
if self.bit_array[index] == 0:
return False
return True
bf = BloomFilter(10000000, [
pyhash.fnv1_32(),
pyhash.fnv1a_32(),
pyhash.metro_64(),
pyhash.murmur3_32(),
pyhash.siphash(),
])
urls = ['http://www.baidu.com', 'http://www.google.com', 'http://www.sina.com.cn']
for url in urls:
if bf.contains(url):
print('{} is already crawled'.format(url))
else:
bf.add(url)
print('Start crawling for {}'.format(url))
2. Scrapy框架中的去重
Scrapy框架集成了自带的去重功能,默认去重算法是哈希去重。可以通过在settings.py
文件中设置DUPEFILTER_CLASS
来指定去重算法,包括布隆过滤器去重和数据库去重等。
下面演示如何在Scrapy中使用布隆过滤器去重:
import pyhash
from scrapy.dupefilters import BaseDupeFilter
from scrapy.utils.request import request_fingerprint
class BloomFilterDupeFilter(BaseDupeFilter):
def __init__(self, key, bit_size=1<<25, num_hashes=5):
self.key = key
self.bit_size = bit_size
self.num_hashes = num_hashes
self.bloom = BloomFilter(bit_size, [
pyhash.fnv1_32(),
pyhash.fnv1a_32(),
pyhash.metro_64(),
pyhash.murmur3_32(),
pyhash.siphash(),
])
@classmethod
def from_settings(cls, settings):
key = settings.get('DUPEFILTER_CLASS')
bit_size = settings.getint('BLOOM_FILTER_BIT_SIZE')
num_hashes = settings.getint('BLOOM_FILTER_NUM_HASHES')
return cls(key=key, bit_size=bit_size, num_hashes=num_hashes)
def request_seen(self, request):
fp = request_fingerprint(request)
if self.bloom.contains(fp):
return True
else:
self.bloom.add(fp)
return False
将settings.py
文件中的DUPEFILTER_CLASS
指定为上述BloomFilterDupeFilter
类即可使用布隆过滤器去重。需要注意的是,为了提高去重效率,布隆过滤器中的二进制向量长度请设置到2^25以上。
三、小结
网络爬虫中的去重是非常重要的一步。通过理解去重原理,可以选择最合适的去重方法,并在应用实例中进行实践。在Scrapy框架中,我们可以通过自定义去重器来实现布隆过滤器去重。