• 去重以及布隆过滤器


    去重源码分析

    """
    # 去重源码分析
    # from scrapy.core.scheduler import Scheduler
    # Scheduler下:def enqueue_request(self, request)方法判断是否去重
    	if not request.dont_filter and self.df.request_seen(request):
       	Requests对象,RFPDupeFilter对象
    # 如果要自己写一个去重类
    	-写一个类,继承BaseDupeFilter类
      -重写def request_seen(self, request):
      -在setting中配置:DUPEFILTER_CLASS = '项目名.dup.UrlFilter'
    
    # scrapy起始爬取的地址
        def start_requests(self):
            for url in self.start_urls:
                yield Request(url)
              
              
              
              
    -增量爬取(100链接,150个链接)
      -已经爬过的,放到某个位置(mysql,redis中:集合)
      -如果用默认的,爬过的地址,放在内存中,只要项目一重启,就没了,它也不知道我爬过那个了,所以要自己重写去重方案
    -你写的去重方案,占得内存空间更小
    	-bitmap方案
    	-BloomFilter布隆过滤器
      
      
      
    from scrapy.http import Request
    from scrapy.utils.request import request_fingerprint
    
    # 这种网址是一个
    requests1=Request(url='https://www.baidu.com?name=lqz&age=19')
    requests2=Request(url='https://www.baidu.com?age=18&name=lqz')
    
    ret1=request_fingerprint(requests1)
    ret2=request_fingerprint(requests2)
    print(ret1)
    print(ret2)
    
    
    
    # bitmap去重  一个小格表示一个连接地址 32个连接,一个比特位来存一个地址
    # https://www.baidu.com?age=18&name=lqz ---》44
    # https://www.baidu.com?age=19&name=lqz ---》89
    # c2c73dfccf73bf175b903c82b06a31bc7831b545假设它占4个bytes,4*8=32个比特位
    # 存一个地址,占32个比特位
    # 10个地址,占320个比特位
    #计算机计量单位
    # 比特位:只能存0和1
    # 8个比特位是一个bytes
    # 1024bytes=1kb
    # 1024kb=1m
    # 1024m=1g
    
    # 布隆过滤器:安装
    #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
    
    # 布隆过滤器:原理和python中如何使用
    
    
    
    # 自定义集合去重方法的,需要重写下面这个方法
        def request_seen(self, request):
            # 把request对象传入request_fingerprint得到一个值:aefasdfeasd
            # 把request对象,唯一生成一个字符串
            fp = self.request_fingerprint(request)
            #判断fp,是否在集合中,在集合中,表示已经爬过,return True,他就不会再爬了
            if fp in self.fingerprints:
                return True
            # 如果不在集合中,放到集合中
            self.fingerprints.add(fp)
            if self.file:
                self.file.write(fp + os.linesep)
    """
    
  • 相关阅读:
    CPU被挖矿,Redis竟是内鬼!
    图解四种 IO 模型
    用户态和内核态的区别是啥
    关于 RocketMQ ClientID 相同引发的消息堆积的问题
    玩转 ByteBuffer
    RocketMQ Consumer 启动时都干了些啥?
    网络协议之:基于UDP的高速数据传输协议UDT
    dart系列之:安全看我,dart中的安全特性null safety
    JetBrains又出神器啦!Fleet,体验飞一般的感觉
    网络协议之:还在用HTTP代理?弱爆了!快试试SOCKS5
  • 原文地址:https://www.cnblogs.com/yafeng666/p/12688067.html
Copyright © 2020-2023  润新知