Python3 爬虫 Scrapy 与 Redis

Scrapy是一个分布式爬虫的框架,如果把它像普通的爬虫一样单机运行,它的优势将不会被体现出来。因此,要让Scrapy往分布式爬虫方向发展,就需要学习Scrapy与Redis的结合使用。Redis在Scrapy的爬虫中作为一个队列存在。

一、Scrapy_redis的安装和使用

Scrapy自带的待爬队列是deque,而现在需要使用Redis来作为队列,所以就需要将原来操作deque的方法替换为操作Redis的方法。但是,如果要把三轮车换成挖掘机,驾驶员也必须从三轮车驾驶员换成挖掘机驾驶员。Scrapy_redis在这里就充当驾驶员的角色。更准确地说,Scrapy_redis是Scrapy的"组件",它已经封装了使用Scrapy操作Redis的各个方法。

Windows、Linux和Mac OS都可以在CMD或者终端中使用pip安装Scrapy_redis:

pip install scrapy_redis

Scrapy_redis本身非常小,但是由于pip会自动安装依赖,所以它会去检查Scrapy和相关的依赖库是否已经安装。如果已经安装了,会提示需求已经满足(Requirement already satisfied),不会重复安装。

使用Redis缓存网页并自动去重

由于Scrapy_redis已经封装了大部分的流程,所以我们使用它不会有任何难度。

  1. 启动Redis

首先需要把Redis启动起来。对于Mac OS/Linux系统,直接在终端下面输入以下命令并按Enter键:

redis-server

在Windows系统中,通过CMD的cd命令进入存放Redis的文件夹,并运行:

redis-server.exe
  1. 修改爬虫

在前面的代码中,爬虫继承自scrapy.Spider这个父类。这是Scrapy里面最基本的一个爬虫类,只能实现基本的爬虫功能。现在需要把它替换掉,从而实现更高级的功能。

首先需要导入支持Redis的爬虫父类并使用:

from scrapy_redis.spiders import RedisSpider

class Exercise114Spider(RedisSpider): 
  name = "exercise11_4"
  redis_key = 'exercise114spider:start_urls'
  ...

请对比上面这段使用了Scrapy_redis的代码与前面例子中爬虫的代码头部有什么不同。

可以看出,这里爬虫的父类已经改成了RedisSpider,同时多了以下内容:

redis_key = 'exercise114spider:start_urls'

这里的redis_key实际上就是一个变量名,之后爬虫爬到的所有URL都会保存到Redis中这个名为"exercise114spider:start_urls"的列表下面,爬虫同时也会从这个列表中读取后续页面的URL。这个变量名可以任意修改,里面的英文冒号也不是必需的。不过一般习惯上会写成"爬虫名:start_urls"这种形式,这样看到名字就知道保存的是什么内容了。

除了导入的类和redis_key这两点以外,爬虫部分的其他代码都不需要做任何修改。原来解析XPath的代码可以正常工作,原来保存数据到MongoDB的代码也可以正常工作。

实际上,此时已经建立了一个分布式爬虫,只不过现在只有一台计算机。

  1. 修改设置

现在已经把三轮车换成了挖掘机,但是Scrapy按照指挥三轮车的方式指挥挖掘机,所以挖掘机还不能正常工作。因此修改爬虫文件还不行,Scrapy还不能认识这个新的爬虫,还需要修改settings.py

(1)Scheduler

首先是调度Scheduler的替换。这是Scrapy中的调度员。在settings.py中添加以下代码:

# Enables scheduling storing requests queue in redis. 
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

(2)去重

# Ensure all spiders share same duplicates filter through redis. 
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

设置好上面两项以后,爬虫已经可以正常开始工作了。不过我们还可以多设置一些东西使爬虫更好用。

(3)爬虫请求的调度算法

爬虫请求的调度算法,有3种情况可供选择。

① 队列

SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderQueue'

如果不配置调度算法,默认就会使用这种方式。它实现了一个先入先出的队列,先放进Redis的请求会优先爬取。

② 栈

SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderStack'

这种方式,后放入到Redis的请求会优先爬取。

③ 优先级队列

SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderStack'

这种方式,会根据一个优先级算法来计算哪些请求先爬取,哪些请求后爬取。这个优先级算法比较复杂,会综合考虑请求的深度等各个因素。

在实际爬虫开发过程中,从以上3项中选择一种并写到settings.py中即可。

(4)不清理Redis队列

# Don't cleanup redis queues, allows to pause/resume crawls. 
SCHEDULER_PERSIST =True

如果这一项为True,那么Redis中的URL不会被Scrapy_redis清理掉。这样的好处是,爬虫停止了再重新启动,它会从上次暂停的地方开始继续爬取。

如果设置成了False,那么Scrapy_redis每一次读取了URL以后,就会把这个URL删除。爬虫暂停以后再重新启动,它会重新开始爬。

由于现在的爬虫和Redis在同一台计算机上面运行,所以可以不需要配置Redis的信息。Scrapy_redis会默认Redis就运行在现在这台计算机上,IP和端口也都是默认的127.0.0.1和6379。如果Redis不在本地的话,就需要将它们写出来:

REDIS_HOST = '127.0.0.1' #修改为Redis的实际IP地址 
REDIS_PORT = 6379 #修改为Redis的实际端口

二、Scrapy 小结

Scrapy在Windows中的安装最为烦琐,在Mac OS中的安装最为简单。由于Scrapy需要依赖非常多的第三方库文件,因此建议无论使用哪个系统安装,都要将Scrapy安装到Virtualenv创建的虚拟Python环境中,从而避免影响系统的Python环境。

使用Scrapy爬取网页,最核心的部分是构建XPath。而其他的各种配置都是一次配好、终生使用的。由于Scrapy的理念是将数据抓取的动作和数据处理的动作分开,因此对于数据处理的各种逻辑应该让pipeline来处理。数据抓取的部分只需要关注如何使用XPath提取数据。数据提取完成以后,提交给pipeline处理即可。

由于Scrapy爬虫爬取数据是异步操作,所以从一个页面跳到另一个页面是异步的过程,需要使用回调函数。

Scrapy爬取到的数据量非常大,所以应该使用数据库来保存。使用MongoDB会让数据保存工作变得非常简单。要让Scrapy使用MongoDB,只需要在pipeline中配置好数据保存的流程,再在settings.py中配置好ITEM_PIPELINES和MongoDB的信息即可。

使用Redis做缓存是从爬虫迈向分布式爬虫的一个起点。Scrapy安装scrapy_redis组件以后,就可以具备使用Redis的能力。在Scrapy中使用Redis需要修改爬虫的父类,需要在settings.py中设置好爬虫的调度和去重。同时对于Python 3,需要修改scrapy_redis的一行代码,才能让爬虫正常运行。


没有自由的秩序和没有秩序的自由,同样具有破坏性。

相关推荐
chengma_09090918 分钟前
linux离线安装部署redis
linux·redis·bootstrap
数据龙傲天2 小时前
电商数据API接口:连接前端与后端的纽带
大数据·爬虫·python·数据分析·api
✘迟暮3 小时前
WebSocket入门与结合redis
java·redis·websocket·网络协议
用户2404817096213 小时前
AI爬虫:获取数据新助手
爬虫
lovelin+v175030409664 小时前
电商数据API接口:安全与性能的双重挑战
人工智能·爬虫·python·数据分析
虎哥和你一起学编程5 小时前
redis stream轻量级消息队列
java·redis·github
04Koi.6 小时前
Redis--高并发分布式结构
数据库·redis·分布式
james东7 小时前
Redis中的Big key排查和解决思路
数据库·redis·缓存
TravisBytes7 小时前
Redis 发布/订阅模式与消息队列
java·linux·c++·redis·缓存·bootstrap