Python scrapy-redis分布式实例(一)

一、分布式爬虫 scrapy-redis

Scrapy-redis为了实现Scrapy分布式提供了一些以redis为基础的组件

https://github.com/rmax/scrapy-redis/

有能人改变了scrapy的队列调度,将起始的网址从start_urls里分离出来,改为从redis读取,多个客户端可以同时读取同一个redis,从而实现了分布式的爬虫 (比如:打印机,每个用户都可以使用)

需要安装:pip install scrapy_redis 安装命令中间是下划线_, 下载好以后显示是横线-

scrapy-redis架构

Python scrapy-redis分布式实例(一)

Scheduler(调度器):

  • Scrapy的Scrapy queue 换成 redis 数据库, 多个 spider 从同一个 redis-server 获取要爬取request
  • Scheduler 对新的request进行入队列操作, 取出下个要爬取的request给爬虫, 使用Scrapy-redis的scheduler组件

Duplication Filter(指纹去重):

  • 在scrapy-redis中去重是由Duplication Filter组件来实现的, 通过redis的set不重复的特性
  • scrapy-redis调度器从引擎接受request, 并指纹存⼊set检查是否重复, 不重复写⼊redis的request queue

Item Pipeline(管道):

  • 引擎将爬取到的Item给Item Pipeline, scrapy-redis组件的Item Pipeline将爬取到的Item 存⼊redis的items队列里

Base Spider(爬虫):

  • RedisSpider继承了Spider和RedisMixin这两个类, RedisMixin用来从redis读取url的类
  • 我们写个Spider类继承RedisSpider, 调用setup_redis函数去连接redis数据库, 然后设置signals(信号)
  • 当spider空闲时候的signal, 会调用spider_idle函数, 保证spider是一直活着的状态
  • 当有item时的signal, 会调用item_scraped函数, 获取下一个request

二、scrapy-Redis分布式策略:

Python scrapy-redis分布式实例(一)

Slaver端从Master端拿任务(Request/url/ID)进行数据抓取,在抓取数据的同时也生成新任务,并将任务抛给Master。Master端只有一个Redis数据库,负责对Slaver提交的任务进行去重、加入待爬队列。
优点:scrapy-redis默认使用的就是这种策略,我们实现起来很简单,因为任务调度等工作scrapy-redis都已经帮我们做好了,我们只需要继承RedisSpider、指定redis_key就行了。

缺点:scrapy-redis调度的任务是Request对象,里面信息量比较大(不仅包含url,还有callback函数、headers等信息),导致的结果就是会降低爬虫速度、而且会占用Redis大量的存储空间。当然我们可以重写方法实现调度url。

三、将之前某个网修改为基于RedisSpider类的scrapy-redis分布式爬虫项目,将数据存入redis数据库。

(1)item文件不需要修改

(2) spiders爬虫文件,使用RedisSpider类替换之前的Spider类,其余地方做些许改动即可,具体代码如下:

#(1)导包
from scrapy_redis.spiders import RedisSpider
#(2)修改RedisSpider
class SixSpider(RedisSpider):
    name = 'six'
    #(3) redis的键值对名称
    redis_key = 'hsx'

(3) 修改settings文件设置

#过滤操作,资源路径:类
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

#调度器的指定,资源路径
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

#调度器的持久化,断点续爬
SCHEDULER_PERSIST = True

#redis管道代替了原来的管道
ITEM_PIPELINES = {
    # 'example.pipelines.ExamplePipeline': 300,  #本地管道
    'scrapy_redis.pipelines.RedisPipeline': 400,
}
#log等级
LOG_LEVEL = 'DEBUG'

#下载延迟
DOWNLOAD_DELAY = 3

(4) 启动爬虫程序 (注意:在运行之前启动redis服务器)

 scrapy crawl six

执行程序后终端窗口显示如下:

Python scrapy-redis分布式实例(一)

原因:因为没有起始url,需要去redis数据库中创建起始url

解决: 在Master端的redis-cli输入push指令,参考格式:

打开redis-cli客户端,输入以下命令

127.0.0.1:6379> lpush hsx https://www.sixstaredu.com/teacher

说明:
hsx: 是爬虫文件中redis_key = ‘hsx’ 中的值
https://www.sixstaredu.com/teacher: 就是起始网址start_url

Python scrapy-redis分布式实例(一)

通过观察:

redis在scrapy-redis中起到的作用:

1.可以代替调度器,保存request请求对象,分配给各个服务器 — “six:requests”

2.可以代替item,pipelines里面的item保存数据 — “six:items”

3.任务的去重,断点续爬(哪里暂停就从哪里开始) — “six:dupefilter”

(5)获取数据

所有Slaver端将开始爬取数据,数据将保存在Redis数据库中,并共享Redis数据库的请求队列、请求指纹集合和数据队列。

Python scrapy-redis分布式实例(一)

Original: https://blog.csdn.net/hlx20080808/article/details/117981670
Author: 凌冰_
Title: Python scrapy-redis分布式实例(一)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/790941/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球