Python爬虫中的去重处理

一:Python爬虫去重应用场景及基本原理

爬虫中什么业务需要使用去重?

  1. 防止发出重复的请求
  2. 防止存储重复的数据

去重实现的基本原理
根据给定的判断依据和给定的去重容器,将原始数据逐一进行判断,判断去重容器中是否有该数据。如果没有那就把该数据对应的判断依据添加去重容器中,同时标记该数据是不重复数据;如果有就不添加,同时标记该数据是重复数据。
判断依据(原始数据,原始数据特征值)
去重容器(存储判断数据)

二:基于信息摘要算法的去重

信息摘要hash算法指可以将任意长度的文件,字节数据,通过一个算法得到一个固定长度的文件。如MD5(128位),SHA1(160位)等。hash算法得出的结果其实质上就是一串数值,如md5的128位指的是二进制长度,十六进制的长度是32位。一个十六进制等于四个二进制。
特征:只要源文本不同,计算得到的结果必然不同(摘要)
摘要:摘要算法主要用于比对信息源是否一致,因为只要源发生变化,得到的摘要必然不同;而且通常结果要比源短很多,所以称为“摘要”。
因此,利用信息摘要算法能大大降低去重容器的存储空间使用率,并提高判断速度,且由于其强唯一的特征,几乎不存在误判。

from hashlib import md5
m5 = md5()
s = 'life is short, you need python'
m5.update(s.encode())		# 必须传入二进制数据
print(m5.hexdigest())
# 0c653a0b179966f1f99b3a1f38a3f02e

2.1 信息摘要hash算法去重方案实现

实现以下三种方案:

  1. 普通内存版本
  2. Redis持久化版本
  3. MySQL持久化版本

python docker环境的部署与配置见:利用docker搭建Python开发环境
python docker环境的Dockerfile文件配置如下:

# 配置基本的python spider开发环境
FROM python:alpine3.7
# 修改alpine系统源及pip安装源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN mkdir -p /root/.pip
RUN echo -e "[global]\nindex-url = http://mirrors.aliyun.com/pypi/simple/\n[install]\ntrusted-host = mirrors.aliyun.com" > /root/.pip/pip.conf
# 安装开发环境所需要的包
RUN apk add --no-cache build-base &&\
    apk add --no-cache libffi-dev &&\
    pip install ipython &&\
    pip install redis &&\
    pip install pymysql &&\
    pip install sqlalchemy &&\
    pip install six &&\
    pip install w3lib &&\
    apk del build-base

2.2 去重过滤器基类实现

Python爬虫中的去重处理

# __init__.py
# 基于信息摘要算法进行数据的去重判断和存储
import hashlib
class BaseFilter(object):
    '''基于信息摘要算法进行数据的去重判断和存储'''
    def __init__(self, hash_func_nme = 'md5', redis_host = "localhost", redis_port = 6379, redis_password = '', redis_db = 0, redis_key = 'filter', mysql_url = None, mysql_table_name = 'filter'):
        self.redis_host = redis_host
        self.redis_port = redis_port
        self.redis_db = redis_db
        self.redis_password = redis_password
        self.redis_key = redis_key
        self.mysql_url = mysql_url
        self.mysql_table_naem = mysql_table_name
        self.hash_func = getattr(hashlib, hash_func_nme)
        self.storage = self._get_storage()
    def _get_hash_value(self, data):
        '''
        根据给定的数据,返回对应的信息摘要hash值
        :param data: 给定的原始数据(二进制类型的字符串数据)
        :return: hash值
        '''
        hash_obj = self.hash_func()
        hash_obj.update(self._safe_data(data))
        hash_value = hash_obj.hexdigest()
        return hash_value
    def _safe_data(self, data):
        '''
        :param data: 给定的原始数据
        :return: 二进制类型的字符串数据
        '''
        if isinstance(data, bytes):
            return data
        elif isinstance(data, str):
            return data.encode()
        else:
          
  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值