zoukankan      html  css  js  c++  java
  • scrapy-redis

    1、settings.py         配置链接Redis

    REDIS_HOST = '192.168.11.81'        # 主机名
    REDIS_PORT = 6379                   # 端口
    # REDIS_URL = 'redis://user:pass@hostname:9001'       
        # 连接URL(!!!!!!!!! 优先于以上配置)
    REDIS_PARAMS  = {}                                  
            # Redis连接参数
    # REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient' 
            # 指定连接Redis的Python模块,默认redis.StrictRedis
    REDIS_ENCODING = "utf-8"                            
            # redis编码类型  
    View Code

    2、去重

    2.1、源码解析

    dupefilter.py

    # 使用scrapy-redis提供的去重功能,查看源码会发现是基于Redis的集合实现的
    # scrapy 使用has_seen()
    # 去重: 利用redis集合元素不重复 request_seen
    # 返回1 表示添加成功 否则0 失败

    def __init__(self):
        pass
        
    @classmethod
    def from_crawler(cls,crawler):
        pass
        
    @classmethod
    def from_settings(cls,settings):
        server=get_redis_from_settings(cls,settings)  
                # 连接redis数据库
            pass
        
    def request_seen(self,request):           # 利用redis集合元素不重复  request_seen
        fp=self.request_fingerprint(request)  # request的指纹,唯一性
        added=self.server.sadd(self.key,fp)   # k,v 插入redis,返回值added    
                                              # sadd 是个集合
        return added == 0          # 如果added=0,说明已经存在这个请求,就不会再加入队列
                                   # 如果added=1,添加成功
                
    def request_fingerprint(self,request):   # 获取指纹
        return request_fingerprint(request)
        
    def close(self,reason=''):
        self.clear()
    
    def clear(self):
        self.server.delete(self.key)
    
    def log(self,request,spider);
        pass
    源码

    queue.py    队列 栈 有序集合

    # FifoQueue
        #(列表,first in first out 先进后出 )
        # spiderQueue=FifoQueue
    
    # LifoQueue
        #(栈,last in first out 后进先出 )
        # spiderStack=LifoQueue
    
    # PriorityQueue(有序集合)
        # spiderPriorityQueue=PriorityQueue
    
    # 不仅存request 还是存request的优先级 
        # score=-request.priority  目的是 深度优先 score是正数
        # 可以在parse中print(response.request.priority)
    def push()
        pass
    def pop()
    View Code

    2.2、只使用去重,连接配置+...

    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
            #使用scrapy-redis提供的去重功能,查看源码会发现是基于Redis的集合实现的
    
        # 实际工作中:     创建dupe.py
            from scrapy_redis.dupefilter from    RFPDupeFilter
            class MyRFPDupeFilter(RFPDupeFilter):
                pass
            DUPEFILTER_CLASS = "xxxx.dupe.MyRFPDupeFilter"    
    View Code

    3、调度器

    将请求通过pickle序列化,添加到redis:列表或者有序集合,与setting配置
    SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' 有关

    连接配置 + 下面:
        # 测试看看是否需要这个,不一定
        # DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
        
        
        SCHEDULER = "scrapy_redis.scheduler.Scheduler"       
        SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue' 
            # 默认使用优先级队列(默认广度优先),其他:PriorityQueue(有序集合 广度优先) 、
            # FifoQueue(列表 深度优先)、
            # LifoQueue(列表 深度优先)、 
            # 调度器将不重复的任务用pickle序列化后放入共享任务队列,
                   
        SCHEDULER_QUEUE_KEY = '%(spider)s:requests' 
            # 调度器中请求任务序列化后存放在redis中的key  
    
        SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"    
            # 对保存到redis中的request对象进行序列化,默认使用pickle
                            
        SCHEDULER_PERSIST = True       
            #是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空 
                                            
        SCHEDULER_FLUSH_ON_START = False    
            #是否在开始之前清空调度器和去重记录,True=清空,False=不清空 
                                      
        SCHEDULER_IDLE_BEFORE_CLOSE = 10           
            #去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
            #如果没有则立刻返回会造成空循环次数过多,cpu占用率飙升 
                              
        SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter'      
            # 去重规则,在redis中保存时对应的key 
            # import redis
            # conn = redis.Redis(host='127.0.0.1',port=6379)
            # v=conn.keys()
            # print(v)
                
        SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
        # 如果只用scrapy_redis调度器,就用下面的scrapy本身去重
        # SCHEDULER_DUPEFILTER_CLASS = 'scrapy.dupefilter.RFPDupeFilter'
            # 去重规则对应处理的类,
            # 将任务request_fingerprint(request)得到的字符串放入去重队列       
    
        DUPEFILTER_DEBUG = False
    View Code

    4、pipline持久化,item保存到redis

    from scrapy_redis.pipelines import RedisPipeline
    
    # settings.py配置   67 行
    ITEM_PIPELINES={
        'crapy_redis.pipelines.RedisPipeline':400,
        }
        
    # scrapy-redis提供了一个pipeline组件,可以帮我们把item存到redis中
    # import redis
    # conn = redis.Redis(host='127.0.0.1',port=6379)
    # v = conn.keys()  # 取值
    # print(v)
    # conn.flushall()  # 清空redis数据
    # 然后不停的生产(往redis中放数据),接着不停的存到某处(消费者)
    # 将item持久化到redis时,指定key和序列化函数 
        # REDIS_ITEMS_KEY = '%(spider)s:items' 
        # REDIS_ITEMS_SERIALIZER = 'json.dumps'
    View Code
  • 相关阅读:
    洛谷 1339 最短路
    洛谷 1330 封锁阳光大学 图论 二分图染色
    洛谷 1262 间谍网络 Tarjan 图论
    洛谷 1373 dp 小a和uim之大逃离 良心题解
    洛谷 1972 莫队
    洛谷 2158 数论 打表 欧拉函数
    洛谷 1414 数论 分解因数 水题
    蒟蒻的省选复习(不如说是noip普及组复习)————连载中
    关于筛法
    关于整数划分的几类问题
  • 原文地址:https://www.cnblogs.com/nick477931661/p/9141151.html
Copyright © 2011-2022 走看看