布隆过滤器是一种高效的空间数据结构,用于快速检测元素是否存在于集合中,尤其适用于爬虫中URL去重。其核心优势是低内存占用和快速查询,但存在一定误判率(假阳性,绝不会假阴性)。
使用 mmh3
哈希库和 bitarray
实现简单布隆过滤器:
import mmh3
from bitarray import bitarray
class BloomFilter:
def __init__(self, size, hash_count):
self.size = size
self.hash_count = hash_count
self.bit_array = bitarray(size)
self.bit_array.setall(0)
def add(self, url):
"""添加URL到过滤器"""
for seed in range(self.hash_count):
index = mmh3.hash(url, seed) % self.size
self.bit_array[index] = 1
def exists(self, url):
"""检查URL是否可能已存在"""
for seed in range(self.hash_count):
index = mmh3.hash(url, seed) % self.size
if self.bit_array[index] == 0:
return False
return True
公式:
m = -(n * ln(p)) / (ln2)^2
k = (m/n) * ln2
n
:预期元素数量,p
:允许的误判率。示例计算:
若预计处理 1,000,000
个URL,误判率设为 1% (0.01)
:
m ≈ 9,585,059 bits
(约1.14MB)k ≈ 7
个哈希函数。
# 初始化:1百万容量,7个哈希函数,误判率约1%
bf = BloomFilter(9585059, 7)
url1 = "https://example.com"
url2 = "https://new-url.com"
bf.add(url1)
print(bf.exists(url1)) # 输出 True(准确判断)
print(bf.exists(url2)) # 输出 False(或小概率True,误判)
O(k)
(k为哈希函数数)。通过合理设计参数,布隆过滤器能够以极小的内存代价,高效处理海量URL去重问题。