在上一篇文章:Scrapy入门教程实例 简单介绍了Scrapy以及用Scrapy创建一个爬虫入门项目,但Scrapy是一个通用的爬虫框架,多个spider不能共享待爬取的队列,因此不支持分布式。
Scrapy-redis
本文要介绍的Scrapy-redis,是一个以redis为基础的Scrapy组件,能够更方便地实现Scrapy分布式爬取。
Scrapy-redis架构如下图:
从上面的架构图,我们可以看出Scrapy-redis在Scrapy架构上增加了redis,基于redis的特性拓展了下面几个组件:
1、Scheduler
Scrapy请求的处理在调度器中进行,Scrapy-redis将数据放到redis数据库队列中处理
2、Duplication Filter
这个组件主要是实现对request去重功能。原先Scrapy把请求指纹放在python集合中处理,而Scrapy-redis利用redis的set不重复性,将request去重工作放在redis中进行。
3、Item Pipeline
引擎将(Spider返回的)爬取到的Item给Item Pipeline,scrapy-redis 的Item Pipeline将爬取到的 Item 存⼊redis的 items queue。
修改过Item Pipeline
可以很方便的根据 key 从 items queue 提取item,从⽽实现items processes
集群。
4、Base Spider
Scrapy-redis不再使用scrapy原有的spider类,重写的RedisSpider继承了Spider和RedisMixin两个类,其中RedisMixin是用来从redis读取url的类。
基于之前创建的Scrapy爬虫,将其修改为Scrapy-redis分布式爬虫。
1、安装redis数据库,具体的安装及配置步骤自行百度,这里就不在介绍。
2、安装Scrapy-redis
pip install scrapy-redis
3、修改爬虫文件
- 导入分布式爬虫类
- 修改爬虫的继承
- 注销allowed_domains和start_urls
- 重写__init__()方法(可选)
- 添加redis_key
具体代码如下(基于上一篇文章的csdn.py修改)
# -*- coding: utf-8 -*-
import scrapy
import re
from scrapy import Request
from csdnblog.items import CsdnblogItem
from scrapy_redis.spiders import RedisSpider
class SpiderCsdnblogSpider(RedisSpider):
name = 'spider_csdnblog'
redis_key = "blog_article:start_urls"
def parse(self, response):
item = CsdnblogItem()
item['url'] = response.url
item['title'] = response.xpath('//h1[@class="title-article"]/text()').extract()[0].encode('utf-8')
item['releaseTime'] = response.xpath('//span[@class="time"]/text()').extract()[0].encode('utf-8')
# data = response.xpath('//div[@class="markdown_views"]')
# item['article'] = data.xpath('string(.)').extract()[0]
yield item
4、修改配置文件settings.py
# -*- coding: utf-8 -*-
BOT_NAME = 'csdnblog'
SPIDER_MODULES = ['csdnblog.spiders']
NEWSPIDER_MODULE = 'csdnblog.spiders'
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
# 使用scrapy-redis里的去重组件,不使用scrapy默认的去重方式
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis里的调度器组件,不使用默认的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 允许暂停,redis请求记录不丢失
SCHEDULER_PERSIST = True
# 默认的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 的 RedisPipeline
ITEM_PIPELINES = {
# 'csdnblog.pipelines.CsdnblogPipeline': 300,
'scrapy_redis.pipelines.RedisPipeline': 300
}
# Introduce an artifical delay to make use of parallelism. to speed up the
# crawl.
DOWNLOAD_DELAY = 1
# 指定数据库的主机IP
REDIS_HOST = "192.168.163.1"
# 指定数据库的端口号
REDIS_PORT = 6379
REDIS_PARAMS = {
'password': '123456' # redis密码(redis数据有配置密码访问需配置)
}
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
5、启动爬虫,往redis数据库端执行下面命令:
redis-cli> lpush blog_article:start_urls https://blog.csdn.net/Hampton_Chen/article/details/81147110
我们可以看到https://blog.csdn.net/Hampton_Chen/article/details/81147110为起始URL,爬虫开始爬取数据。
本文为作者学习爬虫写的总结,如有不足之处,望各位大佬多多指教。