Scrapy-Redis 介绍
Scrapy-Redis
是一个基于Redis
实现的 Scrapy 分布式爬虫组件。Scrapy 本身是一个强大的 Python爬虫框架,但它默认是单进程单线程的,在面对大规模数据抓取任务时效率不高。Scrapy-Redis
则解决了这一问题,它允许你将 Scrapy爬虫扩展到多个机器上运行,从而实现分布式爬虫的功能。
Scrapy-Redis 主要提供了以下几个核心功能:
1.调度器(Scheduler):Scrapy-Redis
提供了一个基于 Redis
的调度器,用于管理待爬取的请求队列。不同的爬虫实例可以从这个共享的队列中获取请求,避免了请求的重复抓取。
2.去重过滤器(DupeFilter):使用 Redis
的集合(set
)数据结构实现了请求去重的功能,确保每个请求只被处理一次。
3.管道(Pipeline):支持将爬取到的数据存储到 Redis
中,方便后续的处理和分析。
4.分布式爬虫:多个爬虫实例可以同时从 Redis
中获取任务,并行地进行数据抓取,大大提高了爬虫的效率。
Scrapy-Redis 使用步骤
1. 安装 Scrapy-Redis
pip install scrapy-redis
2. 创建 Scrapy 项目
scrapy startproject myproject
cd myproject
scrapy genspider myspider example.com
3. 配置 Scrapy 项目
在 settings.py
文件中进行以下配置:
# ///
# 启用 Redis 调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 确保所有爬虫共享相同的去重过滤器
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 允许暂停和恢复爬虫,请求队列会保存在 Redis 中
SCHEDULER_PERSIST = True
# 配置 Redis 服务器地址
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
# REDIS_URL = 'redis://localhost:6379' # 或者这样
# 配置管道,将数据存储到 Redis 中
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300
}
# ///
4. 修改爬虫代码
在 myspider.py
中,让你的爬虫继承自 RedisSpider
:
import scrapy
from scrapy_redis.spiders import RedisSpider
class MySpider(RedisSpider):
name = 'myspider'
# 从 Redis 中获取起始 URL 的键名
redis_key = 'myspider:start_urls'
def parse(self, response):
# 解析响应内容
item = {'url': response.url}
yield item
5. 启动 Redis 服务器
确保你的 Redis 服务器已经启动:
redis-server
6. 向 Redis 中添加起始 URL
使用 Redis 客户端向 Redis 中添加起始 URL:
redis-cli lpush myspider:start_urls http://example.com
7. 启动爬虫
在项目目录下启动爬虫:
scrapy crawl myspider
爬取目标
目标网址:https://movie.douban.com/top250?start=0&filter=
爬取豆瓣电影的Top250
Redis
中的起始 URL 列表(douban:start_urls
)添加第一页的URL
lpush douban:start_urls https://movie.douban.com/top250?start=0&filter=
顺便配置一下记录数据的爬取时间的管道
from datetime import datetime
class DoubanScrapyPipeline:
def process_item(self, item, spider):
item['crawled_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
item['spider'] = spider.name
return item
爬虫代码
class DoubanSpider(RedisSpider):
name = 'douban'
# 从 Redis 中获取起始 URL 的键名
redis_key = 'douban:start_urls'
def parse(self, response: HtmlResponse, **kwargs):
print(f"Extracted URL: {response.url}")
# 解析响应内容
li_list = response.xpath('//ol[@class="grid_view"]/li')
for li in li_list:
item = dict()
item['title'] = li.xpath('.//span[@class="title"]/text()').get()
item['rating'] = li.xpath('.//span[@class="rating_num"]/text()').get()
item['quote'] = li.xpath('.//p[@class="quote"]/span/text()').get()
yield item
运行爬虫之后,redis中就会多一个items