8- scrapy-redis分布式开发
scrapy-redis
scrapy-redis是scrapy的一个组件。
Scrapy_redis在scrapy的基础上实现了更多,更强大的功能,具体体现在:reqeust去重,爬虫持久化,和轻松实现分布式。
安装:
1 | pip install scrapy - redis |
复习redis的使用
列表的简单使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 向列表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 |
集合的简单使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 向集合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 |
有序集合的简单使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # 向有序 集合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源码文件
1 | git clone https: / / github.com / rolando / scrapy - redis.git |
研究项目自带的三个demo
1 | mv scrapy - redis / example - project ~ / Desktop |
Scrapy_redis之domz
这个和我们自己写的crawlSpider没有任何的区别
原先的start_urls中的请求地址不能用了,在我们请求的时候,会提示我们跳转到另外一个网页,这时我们要将跳转后网页的地址复制到start_urls中,并把allowde_domains中的域给改了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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的链接地址
完整的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # 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的链接地址 |
运行爬虫
1 | scrapy crawl dmoz |
我们在redis中会发现多了3个键,分别查看他们的数量
我们可以尝试在setting中关闭scrapy_redispipeline,观察redis中三个键的存储数据量的变化
运行爬虫
1 | 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理