8- scrapy-redis分布式开发
scrapy-redis
scrapy-redis是scrapy的一个组件。
Scrapy_redis在scrapy的基础上实现了更多,更强大的功能,具体体现在:reqeust去重,爬虫持久化,和轻松实现分布式。
安装:
pip install scrapy-redis
复习redis的使用
列表的简单使用
# 向列表mylist中添加值 lpush mylist 1 2 3 4 (integer) 4 keys * "mylist" type mylist list # 查看列表mylist中的所有值 lrange mylist 0 -1 1) "4" 2) "3" 3) "2" 4) "1" # 查看列表mylist的长度 llen mylist (integer) 4
集合的简单使用
# 向集合myset中添加值 ,默认去重 sadd myset 1 2 3 33 3 (integer) 4 # 查看集合myset中的所有值 smembers myset 1) "1" 2) "2" 3) "3" 4) "33" # 查看集合myset中值的数量 scard myset (integer) 4
有序集合的简单使用
# 向有序 集合myzset中添加值和权重 zadd myzset 0 one 2 two 3 three (integer) 3 # 查看有序集合中的所有值 zrange myzset 0 -1 1) "one" 2) "two" 3) "three" # 查看有序集合中所有的值和权重 zrange myzset 0 -1 withscores 1) "one" 2) "0" 3) "two" 4) "2" 5) "three" 6) "3" # 查看有序集合中值的数量 zcard myzset (integer) 3 #把one的权重修改为4 127.0.0.1:6379[1]> zadd myzset 4 one (integer) 0 # 查看有序集合中所有的值和权重 127.0.0.1:6379[1]> zrange myzset 0 -1 withscores 1) "two" 2) "2" 3) "three" 4) "3" 5) "one" 6) "4"
Scrapy_redis使用(通过下载官方的源码)
clone github scrapy-redis源码文件
git clone https://github.com/rolando/scrapy-redis.git
研究项目自带的三个demo
mv scrapy-redis/example-project ~/Desktop
Scrapy_redis之domz
这个和我们自己写的crawlSpider没有任何的区别
原先的start_urls中的请求地址不能用了,在我们请求的时候,会提示我们跳转到另外一个网页,这时我们要将跳转后网页的地址复制到start_urls中,并把allowde_domains中的域给改了
from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class DmozSpider(CrawlSpider): """Follow categories and extract links.""" name = 'dmoz' allowed_domains = ['dmoztools.net'] start_urls = ['http://dmoztools.net/'] rules = [ Rule(LinkExtractor( #定义了一个url的提取规则,满足匹配的交给callback函数处理 restrict_css=('.top-cat', '.sub-cat', '.cat-item') ), callback='parse_directory', follow=True), ] def parse_directory(self, response): for div in response.css('.title-and-desc'): yield { # 把数据发给引擎处理 'name': div.css('.site-title::text').extract_first(), 'description': div.css('.site-descr::text').extract_first().strip(), 'link': div.css('a::attr(href)').extract_first(), }
查看配置文件settings
下面4行是一些scrapy_redis的配置
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 指定那个去重方法给request对象去重 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 指定Scheduler队列 SCHEDULER_PERSIST = True # 队列的内容是否永久存储,为False的时候还在关闭redis的时候清空redis REDIS_URL = "redis:127.0.0.1:6379" # 指定redis的链接地址
完整的代码
# Scrapy settings for example project # # For simplicity, this file contains only the most important settings by # default. All the other settings are documented here: # # http://doc.scrapy.org/topics/settings.html # SPIDER_MODULES = ['example.spiders'] NEWSPIDER_MODULE = 'example.spiders' USER_AGENT = 'scrapy-redis (+https://github.com/rolando/scrapy-redis)'
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 指定那个去重方法给request对象去重 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 指定Scheduler队列 SCHEDULER_PERSIST = True # 队列的内容是否永久存储,为False的时候还在关闭redis的时候清空redis
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue" #SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue" #SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack" ITEM_PIPELINES = { 'example.pipelines.ExamplePipeline': 300,
'scrapy_redis.pipelines.RedisPipeline': 400, # scrapy_redis实现items保存到redis的pipline } LOG_LEVEL = 'DEBUG' # Introduce an artifical delay to make use of parallelism. to speed up the # crawl. DOWNLOAD_DELAY = 1 REDIS_URL = "redis:127.0.0.1:6379" # 指定redis的链接地址
运行爬虫
scrapy crawl dmoz
我们在redis中会发现多了3个键,分别查看他们的数量
我们可以尝试在setting中关闭scrapy_redispipeline,观察redis中三个键的存储数据量的变化
运行爬虫
scrapy crawl dmoz
在redis中分别查看他们的数量
变化结果:
dmoz:requests 有变化(变多或者变少或者不变)
dmoz:dupefilter 变多
dmoz:items 不变
变化结果分析:
scrapy_redispipeline中仅仅实现了item数据存储到redis的过程,我们可以新建一个pipeline(或者修改默认的ExamplePipeline),让数据存储到任意地方
那么问题来了:以上的这些功能scrapy_redis都是如何实现的呢?
通过以上知识点的学习,我们会发现:
domz相比于之前的spider多了持久化和request去重的功能
在之后的爬虫中,我们可以模仿domz的用法,使用scrapy_redis实现相同的功能
注意:setting中的配置都是可以自己设定的,意味着我们的可以重写去重和调度器的方法,包括是否要把数据存储到redis(pipeline)
动手练习
需求:抓取京东图书的信息
目标:抓取京东图书包含图书的名字、封面图片地址、图书url地址、作者、出版社、出版时间、价格、图书所属大分类、图书所属小的分类、分类的url地址
url:https://book.jd.com/booksort.html