分布式爬虫简单介绍
分布式爬虫,说简单一点,只需要将Request任务队列和dupefilter去重的队列存放在公共的Redis中,共享给不同的主机进行操作,且每个主机都运行着相同的爬虫代码。这样就可以做到分布式。
而对于Scrapy,已经有了一个scrapy_redis组件供我们使用,它实现了以下功能:
- 它将request对象放到了redis的有序集合中,利用该有序集合实现了请求队列;
-
对request对象生成去重指纹对象,也存储到同一redis的集合中,利用request指纹避免发送重复的请求
redis中的集合
上图包含了基于scrapy_redis的分布式爬虫在Redis中自动生成的三个集合。
- requests:存放待爬取的request对象的集合,所有爬虫程序都从该集合中获取任务进行爬取。
- dupefilter:用于去重的指纹对象集合,每一个新的Request对象都会先判断是否已在该集合中,若不存在,再添加进request集合
- items:持久化保存的爬取结果item。
分布式爬虫如何实现
首先,你得先有一个正常的scrapy爬虫,再改造成分布式爬虫即可,按照以下几部实现起来很容易。
1. 编写好普通scrapy爬虫
2. 改造成分布式爬虫(5步)
- 导入scrapy_redis中的分布式爬虫类
- 继承类
- 注销start_url和allowed_domains
- 设置redis-key
- 设置_init_获取允许的域(直接按照示例代码即可)
# ------1.导入分布式爬虫类
from scrapy_redis.spiders import RedisSpider
# ------2. 继承分布式爬虫类
class BookSpider(RedisSpider):
name = 'book'
# ------3. 注释掉allowed_domains及start_urls
# allowed_domains = ['jd.com','p.3.cn']
# start_urls = ['https://book.jd.com/booksort.html']
# ------4. 设置redis-key
redis_key = "jd:book"
# ------5. 设置__init__獲取允許的域
def __init__(self, *args, **kwargs):
domain = kwargs.pop("domain", "")
self.allowed_domains = list(filter(None, domain.split(',')))
super(BookSpider, self).__init__(*args, **kwargs)
3.改写配置文件
直接将redis_scrapy中提供的示例settings文件内容拷贝过来,再按实际改写即可。
ROBOTSTXT_OBEY = False
SPIDER_MODULES = ['JD.spiders']
NEWSPIDER_MODULE = 'JD.spiders'
# 设置重复过滤器的模块
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 设置调取器,scrap_redis中的调度器具备与数据库交互的功能
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 设置当爬虫结束的时候是否保持redis数据库中的去重集合与任务队列
SCHEDULER_PERSIST = True
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"
ITEM_PIPELINES = {
'JD.pipelines.JdPipeline':599,
# 当开启该管道,该管道会把数据同时存到Redis数据库中
'scrapy_redis.pipelines.RedisPipeline': 600,
}
DOWNLOADER_MIDDLEWARES = {
'JD.middlewares.UserAgentMiddleware': 543,
}
# 设置redis数据库地址
REDIS_URL = "redis://127.0.0.1:6379"
LOG_LEVEL = 'DEBUG'
DOWNLOAD_DELAY = 1
也可以直接复制我上面的配置文件,再根据你的少量修改即可。
4.启动分布式爬虫
首先需要连接到redis数据库,按照你设定的redis_key值,往redis中添加起始url,然后启动你的多个爬虫程序,我这里是使用的多个cmd窗口模拟多台服务器,示例如下:
![](https://img.haomeiwen.com/i16394388/795f87045cf7f9e8.png)
运行情况:
![](https://img.haomeiwen.com/i16394388/9c9d4d10ae18f242.png)
这样,一个分布式爬虫就已经运行起来了,它们共享操作redis中的任务队列和去重队列。
网友评论