码迷,mamicode.com
首页 > 其他好文 > 详细

scripy redis

时间:2018-05-17 23:27:21      阅读:634      评论:0      收藏:0      [点我收藏+]

标签:col   dom   优先级队列   lifo   分布式   res   ####   serial   request   

scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序,该组件本质上提供了三大功能:

  • scheduler - 调度器
  • 技术分享图片

     

  • dupefilter - URL去重规则(被调度器使用)
  • pipeline   - 数据持久化

scrapy-redis组件

1. URL去重

a

    a. 利用scrapy-redis做去重规则:
            # ############ 连接redis 信息 #################
            REDIS_HOST = 127.0.0.1                            # 主机名
            REDIS_PORT = 6379                                   # 端口
            # REDIS_URL = ‘redis://user:pass@hostname:9001‘       # 连接URL(优先于以上配置)
            REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {‘socket_timeout‘: 30,‘socket_connect_timeout‘: 30,‘retry_on_timeout‘: True,‘encoding‘: REDIS_ENCODING,})
            # REDIS_PARAMS[‘redis_cls‘] = ‘myproject.RedisClient‘ # 指定连接Redis的Python模块  默认:redis.StrictRedis
            REDIS_ENCODING = "utf-8"


            # 自定义去重规则
            DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
                

 

  如果想要对redis-scrapy的去重规则进行扩展:

可以自定义一个去重的类
dup.py
from scrapy_redis.dupefilter import RFPDupeFilter class MyRFPDupeFilter(RFPDupeFilter):
            #继承那个类然后写一些自己定义的方法
pass # 在setting中选择自己自定义去重规则 DUPEFILTER_CLASS = "wenwen.dup.MyRFPDupeFilter"

 

 源码解读

scrapy_redis中的dupefilter

 

 技术分享图片

 

 技术分享图片

 

 

技术分享图片

 技术分享图片

 

使用scrapy-redis组件:

情况一:只用它的去重规则功能

配置:
                    # ############ 连接redis 信息 #################
                    REDIS_HOST = 127.0.0.1                            # 主机名
                    REDIS_PORT = 6379                                   # 端口
                    # REDIS_URL = ‘redis://user:pass@hostname:9001‘       # 连接URL(优先于以上配置)
                    REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {‘socket_timeout‘: 30,‘socket_connect_timeout‘: 30,‘retry_on_timeout‘: True,‘encoding‘: REDIS_ENCODING,})
                    # REDIS_PARAMS[‘redis_cls‘] = ‘myproject.RedisClient‘ # 指定连接Redis的Python模块  默认:redis.StrictRedis
                    REDIS_ENCODING = "utf-8"


                    # 自定义去重规则  如果是自定义去重规则的话详见上文
                    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

情况二:只用它的调度器

                # ############ 连接redis 信息 #################
                REDIS_HOST = 127.0.0.1                            # 主机名
                REDIS_PORT = 6379                                   # 端口
                # REDIS_URL = ‘redis://user:pass@hostname:9001‘       # 连接URL(优先于以上配置)
                REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {‘socket_timeout‘: 30,‘socket_connect_timeout‘: 30,‘retry_on_timeout‘: True,‘encoding‘: REDIS_ENCODING,})
                # REDIS_PARAMS[‘redis_cls‘] = ‘myproject.RedisClient‘ # 指定连接Redis的Python模块  默认:redis.StrictRedis
                REDIS_ENCODING = "utf-8"


                # 有引擎来执行:自定义调度器
                SCHEDULER = "scrapy_redis.scheduler.Scheduler"
                SCHEDULER_QUEUE_CLASS = scrapy_redis.queue.LifoQueue  # 默认使用优先级队列(默认广度优先),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
                SCHEDULER_QUEUE_KEY = %(spider)s:requests  # 调度器中请求存放在redis中的key
                SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"  # 对保存到redis中的数据进行序列化,默认使用pickle
                SCHEDULER_PERSIST = True  # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
                SCHEDULER_FLUSH_ON_START = False  # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
                # SCHEDULER_IDLE_BEFORE_CLOSE = 10  # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
                SCHEDULER_DUPEFILTER_KEY = %(spider)s:dupefilter  # 去重规则,在redis中保存时对应的key  chouti:dupefilter
                SCHEDULER_DUPEFILTER_CLASS = scrapy.dupefilter.RFPDupeFilter  # 去重规则对应处理的类
                #去重规则对应处理的类
                DUPEFILTER_DEBUG = False

情况三:去重+调度去 

# ############ 连接redis 信息 #################
                REDIS_HOST = 127.0.0.1                            # 主机名
                REDIS_PORT = 6379                                   # 端口
                # REDIS_URL = ‘redis://user:pass@hostname:9001‘       # 连接URL(优先于以上配置)
                REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {‘socket_timeout‘: 30,‘socket_connect_timeout‘: 30,‘retry_on_timeout‘: True,‘encoding‘: REDIS_ENCODING,})
                # REDIS_PARAMS[‘redis_cls‘] = ‘myproject.RedisClient‘ # 指定连接Redis的Python模块  默认:redis.StrictRedis
                REDIS_ENCODING = "utf-8"


                # 有引擎来执行:自定义调度器
                SCHEDULER = "scrapy_redis.scheduler.Scheduler"
                SCHEDULER_QUEUE_CLASS = scrapy_redis.queue.LifoQueue  # 默认使用优先级队列(默认广度优先),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
                SCHEDULER_QUEUE_KEY = %(spider)s:requests  # 调度器中请求存放在redis中的key
                SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"  # 对保存到redis中的数据进行序列化,默认使用pickle
                SCHEDULER_PERSIST = True  # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
                SCHEDULER_FLUSH_ON_START = False  # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
                # SCHEDULER_IDLE_BEFORE_CLOSE = 10  # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
                SCHEDULER_DUPEFILTER_KEY = %(spider)s:dupefilter  # 去重规则,在redis中保存时对应的key  chouti:dupefilter
                SCHEDULER_DUPEFILTER_CLASS = scrapy_redis.dupefilter.RFPDupeFilter  # 去重规则对应处理的类
                DUPEFILTER_DEBUG = False

情况四:使用scrapy-redis内置的pipeline做持久化:就是将item对象保存到redis的列表中。

配置:
                 导入scrapy_redis的pipline 
            技术分享图片
          #使用scrapy_pipeline的
                    ITEM_PIPELINES = {
                       scrapy_redis.pipelines.RedisPipeline: 300,
                    }
                以上功能全部应用的配置:
                    # ############ 连接redis 信息 #################
                    REDIS_HOST = 127.0.0.1                            # 主机名
                    REDIS_PORT = 6379                                   # 端口
                    # REDIS_URL = ‘redis://user:pass@hostname:9001‘       # 连接URL(优先于以上配置)
                    REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {‘socket_timeout‘: 30,‘socket_connect_timeout‘: 30,‘retry_on_timeout‘: True,‘encoding‘: REDIS_ENCODING,})
                    # REDIS_PARAMS[‘redis_cls‘] = ‘myproject.RedisClient‘ # 指定连接Redis的Python模块  默认:redis.StrictRedis
                    REDIS_ENCODING = "utf-8"

                    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

                    # 有引擎来执行:自定义调度器
                    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
                    SCHEDULER_QUEUE_CLASS = scrapy_redis.queue.LifoQueue  # 默认使用优先级队列(默认广度优先),其他:PriorityQueue(有序集合),FifoQueue(列表)、LifoQueue(列表)
                    SCHEDULER_QUEUE_KEY = %(spider)s:requests  # 调度器中请求存放在redis中的key
                    SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"  # 对保存到redis中的数据进行序列化,默认使用pickle
                    SCHEDULER_PERSIST = True  # 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
                    SCHEDULER_FLUSH_ON_START = False  # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
                    # SCHEDULER_IDLE_BEFORE_CLOSE = 10  # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
                    SCHEDULER_DUPEFILTER_KEY = %(spider)s:dupefilter  # 去重规则,在redis中保存时对应的key  chouti:dupefilter
                    SCHEDULER_DUPEFILTER_CLASS = scrapy_redis.dupefilter.RFPDupeFilter  # 去重规则对应处理的类
                    DUPEFILTER_DEBUG = False


                    # 深度和优先级相关
                    DEPTH_PRIORITY = 1
            

情况五:让scrapy-redis的起始URL不再通过start_reuqests执行,而是去redis中获取。

配置:
                REDIS_START_URLS_BATCH_SIZE = 1
                # REDIS_START_URLS_AS_SET = True # 把起始url放到redis的集合
                REDIS_START_URLS_AS_SET = False # 把起始url放到redis的列表
            
            爬虫:
                from scrapy_redis.spiders import RedisSpider
                from scrapy.http import Request
                from ..items import WenwenItem

                class ChoutiSpider(RedisSpider):
                    name = chouti
                    allowed_domains = [chouti.com]

                    def parse(self, response):
                        # 随着深度的增加、优先级一直在递减
                        print(response)
    
    
            放置起始URL:
                import redis

                conn = redis.Redis(host=127.0.0.1,port=6379)

                # 起始url的Key: chouti:start_urls
                conn.lpush("chouti:start_urls",https://dig.chouti.com/r/ask/hot/12)

 

 

 如果想要自定义去重规则 或者扩展

  

技术分享图片

技术分享图片

 

 

redis知识补充技术分享图片

技术分享图片

技术分享图片

博客

技术分享图片

 自定义调度器

技术分享图片

 

 

技术分享图片

位置

技术分享图片

 

自定义序列化股则(用于处理特殊类型的数据,  如datatime类型)

 

技术分享图片

scripy redis

标签:col   dom   优先级队列   lifo   分布式   res   ####   serial   request   

原文地址:https://www.cnblogs.com/wangkun122/p/9043151.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
分享档案
周排行
mamicode.com排行更多图片
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!