问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

爬虫的去重技术详解:从基本原理到实际应用

创作时间:
作者:
@小白创作中心

爬虫的去重技术详解:从基本原理到实际应用

引用
1
来源
1.
https://cloud.tencent.com/developer/article/2396820

爬虫在数据抓取过程中,经常会遇到重复数据的问题。如何有效地去除重复数据,提高爬虫效率和数据质量,是每个爬虫开发者都需要面对的挑战。本文将介绍几种常见的去重方法,包括信息摘要hash算法、Simhash算法和布隆过滤器,并通过具体的代码示例帮助读者理解这些方法的实现原理和应用场景。

去重基本原理

在爬虫中使用去重技术主要是为了:

  • 防止发出重复的请求
  • 防止存储重复的数据

在爬取网页数据时,避免对同一URL发起重复的请求,这样可以减少不必要的网络流量和服务器压力,提高爬虫的效率。在将爬取到的数据存储到数据库或其他存储系统之前,去除重复的数据条目,确保数据的唯一性和准确性。去重不仅关系到数据的质量,也影响着爬虫的性能和效率。

根据给定的判断依据和给定的去重容器,将原始数据逐一进行判断,判断去重容器中是否有该数据。如果没有那就把该数据对应的判断依据添加去重容器中,同时标记该数据是不重复数据;如果有就不添加,同时标记该数据是重复数据。

临时去重容器指如利用list、set等编程语言的数据结构存储去重数据,一旦程序关闭或重启后,去重容器中的数据就被回收了。使用与实现简单方便;但无法共享、无法持久化。持久化去重容器指如利用redis、mysql等数据库存储去重数据。

信息摘要hash算法

信息摘要hash算法可以将任意长度的文本、字节数据,通过一个算法得到一个固定长度的文本。如MD5(128位)、SHA1(160位)等。摘要算法主要用于比对信息源是否一致,因为只要源发生变化,得到的摘要必然不同;而且通常结果要比源短很多。

以下是一个使用MD5进行去重的Python示例:

import hashlib

def md5_hash(text):
    md5 = hashlib.md5()
    md5.update(text.encode('utf-8'))
    return md5.hexdigest()

def remove_duplicates(data_list):
    unique_list = []
    seen_hashes = set()
    for data in data_list:
        hash_value = md5_hash(data)
        if hash_value not in seen_hashes:
            seen_hashes.add(hash_value)
            unique_list.append(data)
    return unique_list

data_list = ['苹果', '香蕉', '橙子', '苹果', '橙子']
unique_list = remove_duplicates(data_list)
print(unique_list)

在这个示例中,我们首先定义了一个md5_hash函数,用于计算给定文本的MD5哈希值。然后,我们定义了一个remove_duplicates函数,该函数接受一个数据列表,并使用一个集合seen_hashes来存储已经遇到的哈希值。对于列表中的每个数据项,我们计算其哈希值,如果该哈希值尚未出现在seen_hashes集合中,我们将其添加到集合中,并将数据项添加到结果列表unique_list中。最后,我们返回去重后的结果列表。

基于Simhash算法的去重

Simhash算法是一种用于文本相似度计算的哈希算法,可以用于去重处理。Simhash算法是一种局部敏感哈希算法,能实现相似文本内容的去重。

以下是一个使用Simhash算法进行去重的Python示例:

import jieba
from simhash import Simhash

def remove_duplicates(data_list):
    unique_list = []
    seen_hashes = set()
    for data in data_list:
        words = jieba.cut(data)
        simhash_value = Simhash(' '.join(words)).value
        if simhash_value not in seen_hashes:
            seen_hashes.add(simhash_value)
            unique_list.append(data)
    return unique_list

data_list = ['苹果', '香蕉', '橙子', '苹果', '橙子']
unique_list = remove_duplicates(data_list)
print(unique_list)

我们首先导入了jieba库(用于中文分词)和simhash库(用于计算Simhash值)。然后,我们定义了一个remove_duplicates函数,该函数接受一个数据列表,并使用一个集合seen_hashes来存储已经遇到的Simhash值。对于列表中的每个数据项,我们使用jieba库进行分词,然后计算其Simhash值。如果该Simhash值尚未出现在seen_hashes集合中,我们将其添加到集合中,并将数据项添加到结果列表unique_list中。最后,我们返回去重后的结果列表。

Simhash的特征

  • 信息摘要算法:如果原始内容只相差一个字节,所产生的签名也很可能差别很大。
  • Simhash算法:如果原始内容只相差一个字节,所产生的签名差别非常小。

布隆过滤器

布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在集合中。

布隆过滤器的工作原理

  1. 位数组初始化:布隆过滤器首先维护一个bitArray(位数组),在初始状态下所有数据都置为0。
  2. 使用多个哈希函数:当一个元素加入布隆过滤器时,会通过K个不同的哈希函数计算出K个哈希值,这些值对应到位数组中的K个位置,并将这些位置的值置为1。
  3. 误判率与数组大小:布隆过滤器存在一定的误判率,即可能会将不属于集合的元素误判为属于集合。降低误判率通常需要增大位数组的大小。
  4. 查询操作:进行查询时,同样使用那K个哈希函数计算待查询元素的哈希值,并检查位数组中对应的K个位置是否都为1。如果是,则认为元素可能在集合中;如果任一位不为1,则元素肯定不在集合中。
  5. 添加操作:向布隆过滤器中添加元素时,按照上述方法设置位数组中的相应位为1。由于位被设置为1后不会再变回0,所以布隆过滤器不支持删除操作。
  6. 实际应用:布隆过滤器常用于判断一个元素是否可能已经存在于一个大规模数据集中,例如网络爬虫中用于过滤已访问过的URL等场景。
  7. 性能优势:布隆过滤器的主要优点是空间效率和查询速度快,但它的缺点是不能保证100%的准确性,且无法删除元素。
  8. 优化措施:为了减少误判率,可以采用增加位数组大小、使用更多或更强的哈希函数等策略。同时,可以通过计数布隆过滤器等变种来支持元素的删除操作。

布隆过滤器是一种以空间换取时间效率的数据结构,适用于那些可以接受一定误判率但需要快速判断元素是否存在的场景。在设计布隆过滤器时,需要根据实际应用场景和可接受的误判率来选择合适的位数组大小和哈希函数数量。

布隆过滤器的应用场景

  • 网络爬虫:网络爬虫在爬取网页数据时,需要避免爬取相同的URL地址。布隆过滤器可以用于存储已经访问过的URL,从而快速判断一个新的URL是否已经被爬取过,提高爬虫的效率。
  • 反垃圾邮件:在反垃圾邮件系统中,布隆过滤器可以帮助快速判断一封邮件是否可能是垃圾邮件。通过将已知的垃圾邮件特征存储在布隆过滤器中,系统可以在数十亿个邮件列表中迅速识别出可能的垃圾邮件。
  • Web拦截器:在网络安全领域,布隆过滤器可以用作WEB拦截器,快速检查并拦截重复的恶意请求,防止网站被重复攻击。

本文介绍了几种常见的爬虫去重技术,包括信息摘要hash算法、Simhash算法和布隆过滤器。这些技术各有优缺点,在实际应用中可以根据具体需求选择合适的方法。希望本文能帮助读者更好地理解和应用这些去重技术,提高爬虫的效率和数据质量。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号