scrapy-redis详解

scrapy是一个工业化的爬虫框架,应用广泛,功能强大,scrapy-redis作为scrapy功能的增加,主要多的功能是让scrapy支持了分布式,增加了持续去重,增加了断点续爬,增量爬取等功能。最近学习了scrapy-redis的去重方式的源码,这里做一个简单的总结。

这个图片是scrapy-redis的源码的文件结构。从名字中就可以看出大概的作用。connection,从名字中就可以看出来这个是链接数据库的设置,defaults这个是这个框架redis部分默认的设置,dupefilter这个是用来去重的,pipeplines应该是管道,queue这个是队列的,scheduler这个是调度,spider这个里面的简介是Mixin class to implement reading urls from a redis queue,utils这个很明显是个工具类。我们 一个个的来介绍。

首先是connection.py,

从这个图片我们看出一共就这几个功能:1从settings里面获取redis的链接配置,2:获取redis的链接事例。

然后是defaults.py

从图中可以看出这个是关于redis的一些基础的默认的设置

然后是dupeFilter.py

这个主要是用来去重的。RFPDupeFilter继承自 Scrapy 的BaseDupeFilter,实现了 request 去重功能,基于 Scrapy 的 request_fingerprint 生成指纹,并在 Redis 上存储。当收到新的 request,首先生成指纹判断是否存在于已爬取的指纹库内(Redis set),若存在则返回 False,不存在返回 True.总得来说是这样的,这个文件首先获取到redis的server,然后从scrapy的request中获取request的指纹,将这个指纹进行存到redis的去重库中。达到去重的目的。

然后是pipelines.py文件

图里面是pipeline.py下面的RedisPipeline类,从名字可以看出来这个类的功能是从settings里面获取基本的设置,然后就和正常的pipeline文件一样,进行item的传输

然后是queue.py

这个图里面咱们可以看出,是以base为基类,然后被三个队列的类继承。然后进行了pop和push的操作。

  • FifoQueue: 继承 Base,重写了 push 和 pop 方法实现先进先出队列。
  • PriorityQueue: 继承 Base,重写了 push 和 pop 方法实现优先级队列。
  • LifoQueue: 继承 Base,重写了 push 和 pop 方法实现后进先出队列。

然后是schedule.py

这个文件是用来进行调度的

这个文件下只有一个类Scheduler,向前的类一样,一如既往的痛类方法实现外部可以直接调用的两个方法是从爬虫获取settings和crawler,然后又两个比较特殊的函数是def open(self, spider)和def next_request(self)。

open(): 调度器启动时的自动的操作,这里主要实例化了任务队列 queue 和过滤器 dupefilter。

next_request(): 从任务队列取出 request。

最后一个spiders.py文件

这个spider文件有三个类,RedisMixin是一个基类,剩余两个是多继承。

RedisMixin类

1 setup_redis主要是获取redis的server和获取爬虫的idle signal

当爬虫没有请求时,调用空闲信号,那时我们将从redis队列安排新请求。

2 spider_idle主要是 idle 信号处理,这里调用 schedule_next_requests 完成从 Redis 调度

3 make_request_from_data 主要是从redis队列获取ur

4 next_requests这个主要是redis获取url,我从这里看到可以设置url队列在redis的存储的数据格式函数schedule_next_requests从next_requests获取 url 包装为 HttpRequest.

class RedisSpider(RedisMixin, Spider):
    """Spider that reads urls from redis queue when idle.

    Attributes
    ----------
    redis_key : str (default: REDIS_START_URLS_KEY)
        Redis key where to fetch start URLs from..
    redis_batch_size : int (default: CONCURRENT_REQUESTS)
        Number of messages to fetch from redis on each attempt.
    redis_encoding : str (default: REDIS_ENCODING)
        Encoding to use when decoding messages from redis queue.

    Settings
    --------
    REDIS_START_URLS_KEY : str (default: "<spider.name>:start_urls")
        Default Redis key where to fetch start URLs from..
    REDIS_START_URLS_BATCH_SIZE : int (deprecated by CONCURRENT_REQUESTS)
        Default number of messages to fetch from redis on each attempt.
    REDIS_START_URLS_AS_SET : bool (default: False)
        Use SET operations to retrieve messages from the redis queue. If False,
        the messages are retrieve using the LPOP command.
    REDIS_ENCODING : str (default: "utf-8")
        Default encoding to use when decoding messages from redis queue.

    """

    @classmethod
    def from_crawler(self, crawler, *args, **kwargs):
        obj = super(RedisSpider, self).from_crawler(crawler, *args, **kwargs)
        obj.setup_redis(crawler)
        return obj


class RedisCrawlSpider(RedisMixin, CrawlSpider):
    """Spider that reads urls from redis queue when idle.

    Attributes
    ----------
    redis_key : str (default: REDIS_START_URLS_KEY)
        Redis key where to fetch start URLs from..
    redis_batch_size : int (default: CONCURRENT_REQUESTS)
        Number of messages to fetch from redis on each attempt.
    redis_encoding : str (default: REDIS_ENCODING)
        Encoding to use when decoding messages from redis queue.

    Settings
    --------
    REDIS_START_URLS_KEY : str (default: "<spider.name>:start_urls")
        Default Redis key where to fetch start URLs from..
    REDIS_START_URLS_BATCH_SIZE : int (deprecated by CONCURRENT_REQUESTS)
        Default number of messages to fetch from redis on each attempt.
    REDIS_START_URLS_AS_SET : bool (default: True)
        Use SET operations to retrieve messages from the redis queue.
    REDIS_ENCODING : str (default: "utf-8")
        Default encoding to use when decoding messages from redis queue.

    """

    @classmethod
    def from_crawler(self, crawler, *args, **kwargs):
        obj = super(RedisCrawlSpider, self).from_crawler(crawler, *args, **kwargs)
        obj.setup_redis(crawler)
        return obj
  • RedisSpider(RedisMixin, Spiser) 类: 多继承,用 RedisMixin 调度功能覆盖 Spider 原生
  • RedisSpider(RedisMixin, CrawlSpiser) 类: 多继承,用 RedisMixin 调度功能覆盖 CrawlSpider 原生

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值