scrapy-redis插件爬取示例

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介:

爬取新闻新浪页面

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
items.py
import  scrapy
class  SinaItem(scrapy.Item):
     # define the fields for your item here like:
     # name = scrapy.Field()
     pass
 
class  SinanewsItem(scrapy.Item):
     #大类的标题和url
     parentTitle  =  scrapy.Field()
     parentUrls  =  scrapy.Field()
 
     #小类的标题和子url
     subTitle  =  scrapy.Field()
     subUrls  =  scrapy.Field()
 
     #小类目录存储路径
     subFilename  =  scrapy.Field()
 
     #小类下的子链接
     sonUrl  =  scrapy.Field()
 
     #文章标题和内容
     head  =  scrapy.Field()
     content  =  scrapy.Field()
     
爬虫脚本sina01.py
# -*- coding: utf-8 -*-
import  scrapy
from  ..items  import  SinanewsItem
from  scrapy_redis.spiders  import  RedisSpider
 
 
class  Sina01Spider(RedisSpider):
     name  =  'sina01'
     #启动爬虫时的命令
     redis_key  =  "sinaspider:start_urls"
 
     #allowed_domains = ['sina.com']
     # start_urls = ['http://sina.com/']
 
     #动态定义爬虫取域范围
     def  __init__( self * args,  * * kwargs):
         domain  =  kwargs.pop( 'domain' , '')
         self .allowed_domains  =  filter ( None , domain.split( ',' ))
         super (Sina01Spider,  self ).__init__( * args,  * * kwargs)
 
 
     def  parse( self , response):
         items  =  []
         #所有大类的url和标题
         parentUrls  =  response.xpath( '//div[@id="tab01"]/div/h3/a/@href' ).extract()
         parentTitle  =  response.xpath( '//div[@id="tab01"]/div/h3/a/text()' ).extract()
 
         #所有小类的url和标题
         subUrls  =  response.xpath( '//div[@id="tab01"]/div/ul/li/a/@href' ).extract()
         subTitle  =  response.xpath( '//div[@id="tab01"]/div/ul/li/a/text()' ).extract()
 
         #爬取所有大类
         for  in  range ( 0 len (parentTitle)):
             #爬取所有小类
             for  in  range ( 0 len (subUrls)):
                 item  =  SinanewsItem()
                 #保存大类的title和urls
                 item[ 'parentTitle' =  parentTitle[i]
                 item[ 'parentUrls' =  parentUrls[i]
 
                 #检查小类的url是否以同类别大类url开头,如果是返回True
                 if_belong  =  subUrls[j].startswith(item[ 'parentUrls' ])
 
                 if  (if_belong):
                     # 存储小类url、title和filename字段数据
                     item[ 'subUrls' =  subUrls[j]
                     item[ 'subTitle' =  subTitle[j]
                     items.append(item)
         # 发送每个小类url的Request请求,得到Response连同包含meta数据 一同交给回调函数 second_parse 方法处理
         for  item  in  items:
             yield  scrapy.Request(url = item[ 'subUrls' ], meta = { 'meta_1' :item}, callback = self .second_parse)
 
     #对于返回的小类的url,在进行递归请求
     def  second_parse( self , response):
         #提取每次Response的meta数据
         meta_1  =  response.meta[ 'meta_1' ]
         #取出小类的所有子链接
         sonUrls  =  response.xpath( '//a/@href' ).extract()
 
         items  =  []
         for  in  range ( 0 len (sonUrls)):
             #检查每个链接是否以大类url开头、以.shtml结尾,如果是返回True
             if_belong  =  sonUrls[i].endswith( '.shtml' and  sonUrls[i].startwith(meta_1[parentUrls])
             # 如果属于本大类,获取字段值放在同一个item下便于传输
             if (if_belong):
                 item  =  SinanewsItem()
                 item[ 'parentTitle' =  meta_1[ 'parentTitle' ]
                 item[ 'parentUrls' =  meta_1[ 'parentUrls' ]
                 item[ 'subUrls' =  meta_1[ 'subUrls' ]
                 item[ 'subTitle' =  meta_1[ 'subTitle' ]
                 item[ 'sonUrls' =  sonUrls[i]
                 items.append(item)
 
         # 发送每个小类下子链接url的Request请求,得到Response后连同包含meta数据 一同交给回调函数 detail_parse 方法处理
         for  item  in  items:
             yield  scrapy.Request(url = item[ 'sonUrls' ],meta = { 'meta_2' :item},callback = self .detail_parse)
 
         #数据解析方法,获取文章标题和内容
         def  detail_parse( self , response):
             item  =  response.meta[ 'meta_2' ]
             content  =  ""
             head  =  response.xpath( '/h1[@id="main_title"]/text()' )
             content_list  =  response.xpath( '//div[@id="artibody"]/p/text()' ).extract()
 
             #将p标签里的文本内容 合并到一起
             for  content_one  in  content_list:
                 content  + =  content_one
 
             item[ 'head' =  head[ 0 if  len (head) >  0  else  "NULL"
             item[ 'content' =  content
 
             yield  item
             
  settings.py添加
  # 使用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"
 
# 只是将数据放到redis数据库,不需要写pipelines文件
ITEM_PIPELINES  =  {
#    'Sina.pipelines.SinaPipeline': 300,
     'scrapy_redis.pipelines.RedisPipeline' 400 ,
}
 
# LOG_LEVEL = 'DEBUG'
 
# Introduce an artifical delay to make use of parallelism. to speed up the
# crawl.
DOWNLOAD_DELAY  =  1
# 指定数据库的主机IP
REDIS_HOST  =  "localhost"
# 指定数据库的端口号
REDIS_PORT  =  6379 
 
打开redis客户端添加url测试
lpush sinaspider:start_urls http: / / news.sina.com.cn / guide /


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
NoSQL 数据可视化 Redis
Datagrip2020连接redis,可视化插件安装
Datagrip2020连接redis,可视化插件安装
817 0
|
3月前
|
缓存 NoSQL Java
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
|
6月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
2月前
|
缓存 NoSQL PHP
使用PHP-redis实现键空间通知监听key失效事件的技术与代码示例
通过上述方法,你可以有效地在PHP中使用Redis来监听键空间通知,特别是针对键失效事件。这可以帮助你更好地管理缓存策略,及时响应键的变化。
96 3
|
4月前
|
缓存 NoSQL Serverless
函数计算产品使用问题之如何使用Redis作为缓存插件
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
116 8
|
6月前
|
缓存 Rust NoSQL
Higress 基于自定义插件访问 Redis
本文介绍了Higress,一个支持基于WebAssembly (WASM) 的边缘计算网关,它允许用户使用Go、C++或Rust编写插件来扩展其功能。文章特别讨论了如何利用Redis插件实现限流、缓存和会话管理等高级功能。
153491 32
|
4月前
|
数据采集 存储 缓存
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
|
5月前
|
Web App开发 iOS开发 Python
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
40 0
|
XML 数据采集 JSON
scrapy_selenium爬取Ajax、JSON、XML网页:豆瓣电影
在网络爬虫的开发过程中,我们经常会遇到一些动态加载的网页,它们的数据不是直接嵌入在HTML中,而是通过Ajax、JSON、XML等方式异步获取的。这些网页对于传统的scrapy爬虫来说,是很难直接解析的。那么,我们该如何使用scrapy_selenium来爬取这些数据格式的网页呢?本文将为你介绍scrapy_selenium的基本原理和使用方法,并给出一个实际的案例。
112 0
|
6月前
|
数据采集 JavaScript 开发者
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
下一篇
无影云桌面