您当前的位置: 首页 >  redis

IT之一小佬

暂无认证

  • 2浏览

    0关注

    1192博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Scrapy_redis框架原理分析并实现断点续爬以及分布式爬虫

IT之一小佬 发布时间:2021-12-28 16:38:16 ,浏览量:2

1. 下载github的demo代码 1.1 clone github scrapy-redis源码文件
git clone https://github.com/rolando/scrapy-redis.git

 cd到示例项目中:

安装缺少的scrapy-redis模块: pip install scrapy-redis

 启动爬虫:

 把启动的爬虫中止,在RDM中查看爬虫的结果:

 此时发现数据队列中有174条数据,接下来继续启动爬虫,观察数据的变化:

 以上就实现断点续爬。

1.2 研究项目自带的demo
mv scrapy-redis/example-project ~/scrapyredis-project
2. 观察dmoz文件

        在domz爬虫文件中,实现方式就是crawlspider类型的爬虫。

dmoz.py文件

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class DmozSpider(CrawlSpider):
    """Follow categories and extract links."""
    name = 'dmoz'
    allowed_domains = ['dmoz-odp.org']
    start_urls = ['http://www.dmoz-odp.org/']

    # 定义数据提取规则,使用了css选择器
    rules = [
        Rule(LinkExtractor(
            restrict_css=('.top-cat', '.sub-cat', '.cat-item')
        ), callback='parse_directory', follow=True),
    ]

    def parse_directory(self, response):
        for div in response.css('.title-and-desc'):
            yield {
                'name': div.css('.site-title::text').extract_first(),
                'description': div.css('.site-descr::text').extract_first().strip(),
                'link': div.css('a::attr(href)').extract_first(),
            }

        在settings.py中多了以下内容,这几行表示scrapy_redis中重新实现的了去重的类,以及调度器,并且使用RedisPipeline管道类

#  设置重复过滤器的模块
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
#  设置调取器, scrapy_redis中的调度器具备与数据库交互的功能
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
#  设置当爬虫结束的时候是否保持redis数据库中的去重集合与任务队列
SCHEDULER_PERSIST = True

ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    #  当开启该管道,该管道将会把数据库存到redis数据库中
    'scrapy_redis.pipelines.RedisPipeline': 400,
}
#  设置redis数据库
REDIS_URL = "redis://127.0.0.1:6379"
3. 运行dmoz爬虫,观察现象 3.1首先需要添加redis的地址,程序才能够使用redis
REDIS_URL = "redis://127.0.0.1:6379"
#或者使用下面的方式
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379
3.2执行domz的爬虫,会发现redis中多了一下三个键:

3.3中止进程后再次运行dmoz爬虫

        继续执行程序,会发现程序在前一次的基础之上继续往后执行,所以domz爬虫是一个基于url地址的增量式的爬虫

4. scrapy_redis的原理分析

从settings.py中的三个配置来进行分析 分别是:

  • RedisPipeline # 管道类
  • RFPDupeFilter # 指纹去重类
  • Scheduler # 调度器类
  • SCHEDULER_PERSIST # 是否持久化请求队列和指纹集合
4.1 Scrapy_redis之RedisPipeline

RedisPipeline中观察process_item,进行数据的保存,存入了redis中

4.2 Scrapy_redis之RFPDupeFilter

RFPDupeFilter 实现了对request对象的加密

4.3 Scrapy_redis之Scheduler

scrapy_redis调度器的实现了决定什么时候把request对象加入带抓取的队列,同时把请求过的request对象过滤掉

4.4 request对象入队的条件
  • request的指纹不在集合中
  • request的dont_filter为True,即不过滤
    • start_urls中的url地址会入队,因为他们默认是不过滤
5. 实现分布式爬虫 5.1 分析demo中代码

打开example-project项目中的myspider_redis.py文件

通过观察代码:

  1. 继承自父类为RedisSpider
  2. 增加了一个redis_key的键,没有start_urls,因为分布式中,如果每台电脑都请求一次start_url就会重复
  3. 多了__init__方法,该方法不是必须的,可以手动指定allow_domains
  4. 启动方法:
    1. 在每个节点正确的目录下执行scrapy crawl 爬虫名,使该节点的scrapy_redis爬虫程序就位
    2. 在共用的redis中 lpush redis_key 'start_url',使全部节点真正的开始运行
  5. settings.py中关键的配置
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True

ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}
REDIS_URL = "redis://127.0.0.1:6379"
5.2 实现分布式爬虫

以书山有路网为例:详情查看博客:Scrapy_redis框架分布式爬虫的实现案例-书山有路网_IT之一小佬的博客-CSDN博客

注意:启动方式可以用别的方式:scrapy runspider book.py   可以用相对路径,也可以用绝对路径

分布式爬虫的编写流程:

1.编写普通爬虫

  • 创建项目
  • 明确目标
  • 创建爬虫
  • 保存内容

2.改造成分布式爬虫

2.1改造爬虫

  1. 导入scrapy_redis中的分布式爬虫类
  2. 继承类
  3. 注销start_url&allowed_domains
  4. 设置redis_key获取start_urls
  5. 设置__init__获取允许的域

2.2改造配置文件

  • copy配置参数

分布式爬虫使用场景:

  • 数据量特别巨大
  • 数据要求时间比较紧张

分布式的实现:

  • scrapy_redis实现分布式
  • 普通爬虫实现分布式,实现去重集合与任务队列的共享
关注
打赏
1665675218
查看更多评论
立即登录/注册

微信扫码登录

0.1971s