zoukankan      html  css  js  c++  java
  • scrapy的去重规则

    scrapy自带去重策略:

    scrapy通过request_fingerprint函数,对Request对象生成指纹,看注释:

    # 该函数在scrapy/utils/request.py文件中
    def request_fingerprint(request, include_headers=None):
        if include_headers:
            include_headers = tuple(to_bytes(h.lower())
                                     for h in sorted(include_headers))
        cache = _fingerprint_cache.setdefault(request, {})
        if include_headers not in cache:
            fp = hashlib.sha1()
            """计算指纹时,请求方法(如GET、POST)被计算在内"""
            fp.update(to_bytes(request.method)) 
     
            """下面这句有意思,canonicalize_url()将url规范化,意味着
              http://www.example.com/query?id=111&cat=222
              http://www.example.com/query?cat=222&id=111
            这样参数位置变化,但参数值不变的网址,表示的仍是同一个网址,符合现实逻辑。
             """
            fp.update(to_bytes(canonicalize_url(request.url)))
     
            """request.body的属性是字符串:
            一般GET方法的body为空字符串,不考虑;
            而POST方法要上传一个字典data(类型是dict),
            要经过urllib.parse.urlencode()函数转换后才能变成request.body
           """
            fp.update(request.body or b'')
            if include_headers:
                for hdr in include_headers:
                    if hdr in request.headers:
                        fp.update(hdr)
                        for v in request.headers.getlist(hdr):
                            fp.update(v)
            cache[include_headers] = fp.hexdigest()
        return cache[include_headers]
    """我们甚至可以根据需求将request.meta的内容作为指纹计算的一部分"""

    scrapy生成的唯一指纹,存在内存的一个集合里,即set。如果下一次请求产生的指纹在这个set里面,请求被判定为重复,这次请求就被忽略,也就是所谓的去重了。

    示例演示自带去重

    # 指纹去重,用的集合,对url地址取指纹(md5),放到集合中
    from scrapy.utils.request import request_fingerprint
    from scrapy import Request
    r1=Request(url='http://www.baidu.com/?name=lqz&age=18')
    r2=Request(url='http://www.baidu.com/?age=18&name=lqz')
    ret1=request_fingerprint(r1)
    ret2=request_fingerprint(r2)
    print(ret1)
    print(ret2)

    第三方去重:布隆过滤器

    安装:

    #python3.6 安装
    #需要先安装bitarray
    pip3 install bitarray-0.8.1-cp36-cp36m-win_amd64.whl(pybloom_live依赖这个包,需要先安装)
    #下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/
    pip3 install pybloom_live

    使用:

    在爬虫项目下新建py文件

     qc.py

    from scrapy.dupefilters import BaseDupeFilter
    from pybloom_live import ScalableBloomFilter
    
    
    class UrlFilter(BaseDupeFilter):
        def __init__(self):
            self.bloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.001,
                                             mode=ScalableBloomFilter.LARGE_SET_GROWTH)
    
    
    def request_seen(self, request):
        if request.url in self.bloom:
            return True
        self.bloom.add(request.url)

    settings.py中配置

    DUPEFILTER_CLASS = 'cnblogs.qc.UrlFilter'   # 使用自定义的
  • 相关阅读:
    linux 下安装web开发环境
    Nginx服务器之 Nginx的基本配置
    Nginx服务器之基础学习
    java反射 之 反射基础
    java IO流 之 其他流
    java IO流 之 字符流
    java IO流 之 字节流
    java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
    java线程 公平锁 ReentrantLock(boolean fair)
    MarkdownPad 2破解
  • 原文地址:https://www.cnblogs.com/baicai37/p/13449716.html
Copyright © 2011-2022 走看看