如何将scrapy爬虫转换为scrapy_redis爬虫?

注意事项:在阅读本文之前,必须具备使用scrapy编写爬虫的能力。

使用scrapy框架就可以快速开发一个爬虫,如果针对一个大型的网站,单机爬虫就会显得心有余而力不足。那么有没有便捷的办法是单机爬虫转换为分布式爬虫呢?

首先需要了解单机爬虫与分布式爬虫的区别:

我们先来查看两张思维导图:

scrapy 框架实现原理

如何将scrapy爬虫转换为scrapy_redis爬虫?_第1张图片

scrapy_redis 框架实现原理

如何将scrapy爬虫转换为scrapy_redis爬虫?_第2张图片

在上述两张图示中我们可以看到scrapy_redis只是在scrapy的基础之上多了一个redis数据库,正是因为多了redis数据库才是我们能够在scrapy爬虫的基础之上创造出分布式爬虫。

scrapy_redis在redis的基础之上拓展了四个组件,分别如下:

Scheduler

Scrapy改造了python本来的collection.deque(双向队列)形成了自己的Scrapy queue ,scrapy_redis把Scrapy queue换成redis数据库(也是指redis队列),从同一个redis-server存放要爬取的request,便能让多个spider去同一个数据库里读取。

Duplication Filter

Scrapy中用集合实现这个request去重功能,Scrapy中把已经发送的request指纹放入到一个集合中,把下一个request的指纹拿到集合中比对,如果该指纹存在于集合中,说明这个request发送过了,如果没有则继续操作。

scrapy_redis中去重是由Duplication Filter组件来实现的,它通过redis的set 不重复的特性,巧妙的实现了Duplication Filter去重。scrapy_redis调度器从引擎接受request,将request的指纹存⼊redis的set检查是否重复,并将不重复的request push写入redis的request queue。

引擎请求request(Spider发出的)时,调度器从redis的request queue队列⾥里根据优先级pop 出⼀个request 返回给引擎,引擎将此request发给spider处理。

Item Pipeline

引擎将(Spider返回的)爬取到的Item给Item Pipeline,scrapy_redis的Item Pipeline将爬取到的Item 存在redis的items queue。

Base Spider

不在使用scrapy原有的Spider类,重写的RedisSpider继承了Spider和RedisMixin这两个类,RedisMixin是用来从redis读取url的类。

当我们生成一个Spider继承RedisSpider时,调用setup_redis函数,这个函数会去连接redis数据库,然后会设置signals(信号)

  • 一个是当spider空闲时候的signal,会调用spider_idle函数,这个函数调用schedule_next_request函数,保证spider是一直活着的状态,并且抛出DontCloseSpider异常。
  • 一个是当抓到一个item时的signal,会调用item_scraped函数,这个函数会调用schedule_next_request函数,获取下一个request

 

了解了scrapyscrapy_redis的区别之后,如何快速将scrapy爬虫转换为scrapy_redis爬虫呢?

在修改相关代码之前,需要在虚拟环境中安装scrapy_redis框架

具体操作步骤如下:

修改继承

将爬虫的继承类scrapy.Spider转换为scrapy_redis.spider.RedisSpider;或者将scrapy.CrawlSpider转换为scrapy_redis.spider.RedisCrawlSpider

将爬虫的start_urls删除或者注释,增加一个rediskey=”myspider:start_urls”(myspider:start_urls是键值对格式)。这个rediskey是为了以后再redis中控制爬虫启动的。爬虫中的第一个URL就是在redis中通过rediskey发送出去的。

settings中增加相关配置

配置redis数据库

REDIS_HOST=”192.168.X.X” (修改为redis服务器的IP地址)

REDIS_PORT=6379

确保request存储到redis

SCHEDULER=”scrapy_redis.scheduler,Scheduler”

# 确保所有的爬虫共享相同的去重指纹

DUPEFILTER_CLASS=”scrapy_redis.dupefilter.RFPDupeFilter”

设置redisitem pipeline

ITEM_PIPELINES={

   “scrapy_redis.pipeline.RedisPipeline”:100

}

redis中确保scrapy_redis用到的队列在关机时不会清除

SCHEDULER_PERSIST=True

上述步骤完成之后,就可以运行分布式爬虫。

在爬虫服务器上,进入爬虫文件所在的路径,然后输入命令scrapy runspider 爬虫名称,此时启动爬虫并且爬虫处于等待开始爬取状态,这是应为你还没有为爬虫指定开始的URL

redis服务器上,推入一个开始的URL命令如下:

redis-cli > lpush [myspider:start_urls] 爬虫开始爬取的起始URL

此时爬虫就处于爬行状态。

你可能感兴趣的:(scrapy,scrapy_redis,爬虫)