Scrapy_Redis的介绍
Scrapy_redis是一个基于redis的scrapy组件(redis based compontents for scrapy)。Scrapy_redis在Scrapy的基础上实现了更多强大的功能,具体体现在:request去重,爬虫持久化,轻松实现分布式。
Scrapy自带url去重功能,对重复的url不在抓取,我们今天请求过的url,Scrapy不会再抓取,但是我们明天再请求同样的url,那么Scrapy就会抓取,这通常不是我们想要的。我们想要的是今天请求过的url,明天也不要再请求,这时候就可以通过Scrapy_redis来实现。
我们根据Scrapy的流程图,来分析,要想实现url去重,我们的重点就是在存放url的地方,可以放到数据库中,把所有的调度器中的request请求放到redis中,通过redis实现去重。


由于是手画的图片,存在有很多问题。我们只需要把重点放在redis实现调度器队列和指纹集合,通过一个案例,你可能会明白的更多。
腾讯招聘案例演示
我们以腾讯招聘作为演示,首先创建项目和爬虫:
scrapy startproject tencent
cd tencent
scrapy genspider -t crawl tc tencent.com
修改起始的url地址,我们使用CrawlSpider来实现翻页,通过parse_item解析列表页,parse_detail函数解析详情页,非常简单是吧。
但是一番观察发现,事情不是我们预想的呢样,在网页中找不到详情页的url地址,和翻页的地址,它是通过json接口传递的。

我们发现详情页的地址,需要在一个json接口:https://careers.tencent.com/tencentcareer/api/post/Query?&pageIndex=1&pageSize=10中寻找,将PostId和PostURL组合就是详情页的地址。但是详情页的数据也是json接口,所以我们直接构造详情页的URL地址交给parse_detail函数处理,代码参考;
# -*- coding: utf-8 -*-
import scrapy
import json
class TcSpider(scrapy.Spider):
name = 'tc'
allowed_domains = ['careers.tencent.com']
#开始的url是一个json接口,参数非常简单
start_urls = ['https://careers.tencent.com/tencentcareer/api/post/Query?&pageIndex=1&pageSize=10']
def parse(self, response):
#json数据转换为字典可以方便的拿到我们需要的数据
html=json.loads(response.body.decode())
lis=html['Data']['Posts']
for i in lis:
item={}
item['postid'] = i['PostId']
item['name']=i['RecruitPostName']
item['location']=i['LocationName']
item['data']=i['LastUpdateTime']
#构造详情页的url地址,交给parse_detail函数处理
detail = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?postId='
detail_url = detail + item['postid']
yield scrapy.Request(
detail_url,
callback=self.parse_detail,
meta={'item':item}
)
def parse_detail(self,response):
#接收item字典,添加工作介绍和工作要求
item=response.meta['item']
html=json.loads(response.body.decode())
item['Responsibility']=html['Data']['Responsibility']
item['Requirement']=html['Data']['Requirement']
print(item)
翻页的操作很简单就可以实现,可以修改起始url的参数pageIndex页码和pageSize尺寸,我们可以随意修改尺寸就是显示的数量,这个可以直接修改不用翻页也可以。
Scrapy_Redis的安装
我们的重点是用scrapy_redis来实现去重功能,那么首先安装scrapy-redis。我使用的是pycharm,个人比较喜欢使用命令安装,在Terminal的终端输入命令:
pip install --default-timeout=5000 scrapy-redis
设置为不超时,什么时候安装好什么时候退出,避免安装超时。我们怎么使用呢,先看一下演示,使用方法很简单,我么只需要修改settings文件就可以,在此之前你需要了解redis的基本使用,这里不再详细介绍redis的有关知识。
修改腾讯招聘案例为scrapy_redis爬虫
我们只需要在settings文件中添加下面的代码(删掉了注释的代码):
# -*- coding: utf-8 -*-
#指定哪个去重方法结合request对象去重
DUPEFILTER_CLASS='scrapy_redis.dupefilter.RFPDupeFilter'
#指定scheduler队列
SCHEDULER='scrapy_redis.scheduler.Scheduler'
#队列中的内容是否持久保存,为False的时候,关闭redis的同时会清空redis数据
SCHEDULER_PERSIST=True
#SpiderPriorityQueue是scrapy_redis默认使用的队列模式(有自己的优先级)
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
#使用了队列的形式,任务先进先出
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
#采用了栈的形式,任务先进后出
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"
#scrapy_redis实现的item保存到redis的pipeline
ITEM_PIPELINES = {
'tencent.pipelines.TencentPipeline': 300,
'scrapy_redis.pipelines.RedisPipeline':400,
}
DOWNLOAD_DELAY = 1
LOGLEVEL='DEBUG'
#指定redis的地址,为本机
REDIS_URL='redis://127.0.0.1:6379'
BOT_NAME = 'tencent'
SPIDER_MODULES = ['tencent.spiders']
NEWSPIDER_MODULE = 'tencent.spiders'
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
ROBOTSTXT_OBEY = False
然后我们开启redis服务端和客户端,服务端让爬虫操作,客户端来查看一些信息。运行爬虫,然后在redis客户端查看数据。在redis客户端输入:
keys *
1) "tc:requests" #类型zset 待爬的requests对象
2) "tc:items" #类型list
3) "tc:dupefilter" #类型set爬取过的requests指纹
那么使用scrapy_redis爬虫,会在redis数据库中生成固定的一些信息,包括:
- 爬虫名字:requests。schedulter队列,存放待请求的request对象,获取的过程是pop操作,即获取一个会删除一个。
- 爬虫名字:items。存放获取到的item信息,在pipeline中开启RedisPipeline时才会存入。
- 爬虫名字:dupefilter。指纹集合,存放已经进入schedulter队列的request对象的指纹,指纹默认由请求方法,url和请求体组成。
意味着我们不开启scrapy_redis.pipelines.RedisPipeline管道,redis数据库中就不会有items。换句话说scrapy_redis.pipelines.RedisPipeline仅仅实现了item数据存储到redis的过程,那么我们可以新建一个pipeline(或者修改默认的pipeline),让数据存放到任意地方。
我们重点放在redis数据库中的三个新增的键值,reqeusts的解释已经很明确了,这就是问什么我们在爬虫结束的时候,redis数据库中只显示items和dupefilter。爬虫停止的时候意味着,requests没有了请求对象,那么就会删除这个键。你可以修改一下腾讯招聘的json接口,把每页显示的数量增加(pageSize参数的值),尽量修改大一点,这样,你有足够的时间去输入命令查看,在爬虫没有运行完的时候,是存在requests的,具体自己尝试方能悟解!哈哈哈
Scrapy_Redis爬虫源码分析
我们需要真正的了解scrapy_redis原理,那么就需要通过源码。对于小白来说,看懂源码是一件非常有挑战性的困难,但是只有这样才可以不断进步。具体的内容本文不再介绍,篇幅有限,详情可点击:Scrapy_Redis源码介绍和分析。
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!