1. 关于scrapy-redis
scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序
原因:
redis在内存中运行,它可以将抓取的网页内容存入到内存中,因此相对于从磁盘获取数据,redis可以大大提高爬虫爬取效率
scrapy-redis组件提供的三大功能:
- scheduler - 调度器
- dupefilter - URL去重规则
- pipline - 数据持久化
URL去重
定义去重规则(被调度器调用并应用)
- 连接redis
- 去重规则通过redis的集合完成
集合的key为:key = default.DUPEFILTER_KEY % {'timestamp': int(time.time())}
默认配置:DUPEFILTER_KEY = 'dupefilter: % (timestamp)s'
- 去重规则中将url转换成唯一表示,然后再redis中检查是否已经在集合中存在了
from scrapy.utils import request
from scrapy.http import Request
req = Request(url='http://www.baidu.com')
result = request.request_fingerprint(req)
调度器
调度器使用PriorityQueue(有序集合)、FifoQueue(列表)、LifoQueue(列表)进行保存 请求,并且使用RFPDupeFilter对URL去重
数据持久化
定义持久化,爬虫yield Item对象时执行RedisPipline
将item持久化到redis时,指定key和序列化函数
REDIS_ITEM_KEY = '% (spider)s: items'
REDIS_ITEMS_SERIALIZER = 'json.dumps'
使用列表保存item数据
2. 如何将scrapy改为scrapy-redis?
- setting.py文件中参数配置
① 启动redis调度存储请求队列:调度器使用scrapy_redis的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
② 确保所有的爬虫通过redis去重:使用scrapy_redis的去重类
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDuperFilter"
③ 爬取过程中是否允许暂停:不清除redis队列,这样可以暂停/恢复爬取
SCHEDULER_PERSIST = True
④ 连接redis数据库
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
⑤ 在管道中添加一个scrapy_redis管道运行优先级
ITEM_PIPELINES = {'scrapy_redis.piplines.RedisPipline': 400,}
⑥ 最大并发请求量
CONCURRENT_REQUESTS = 32
⑦ 下载延迟:多台设备同时分布式爬取的时候,容易造成所爬取的网站的服务器崩掉
DOWNLIAD_DELAY = 1
- 修改spider文件中的代码
引入scrapy.redis.spider模块
from scrapy_redis.spider import RedisCrawlSpider
class AgentSpider(RedisCrawlSpider):
name = 'Agent'
redis_key = 'agent: start_urls'
- 开启redis服务器、启动项目