分布式爬虫
分布式爬虫
分布式概述
基于多台电脑组建一个分布式机群,然后让机群中的每一台电脑执行同一组程序,然后让它们对同一个网站的数据进行分布爬取
作用:提升爬虫数据的效率
实现:基于scrapy+redis的形式实现分布式,scrapy结合这scrapy-redis组件实现的分布式
原生scrapy无法实现分布式原因:
1.调度器无法被分布式机群共享
2.管道无法被共享
scrapy-redis组件的作用:提供可以被共享的调度器和管道
环境安装:
1.redis
2.pip Install scrapy-redis
使用流程
1.创建一个scrapy工程
2.创建一个爬虫文件
基于CrawlSpider的爬虫文件,也可以是普通spider文件
3.修改当前的爬虫文件
-
导包:from scrapy_redis.spiders import RedisCrawlSpider
如果使用的是普通的spider文件,导入RedisSpider类即可
-
将当前爬虫类的父类修改成RedisCrawlSpider
-
将start_urls替换成redis_key = ‘xxx’
表示的是可被共享调度器中队列的名称
4.编写爬虫类爬取数据的操作
对settings进行配置:
指定管道:
#开启可以被共享的管道
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400
}
指定调度器:
# 增加了一个去重容器类的配置, 使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
SCHEDULER_PERSIST = True
指定redis的服务:
REDIS_HOST = 'redis服务的ip地址'
REDIS_PORT = 6379
redis的配置文件进行配置
redis.windows.conf
- 56行:#bind 127.0.0.1
- 75行:protected-mode no
5.启动redis
携带配置文件启动redis服务:./redis-server redis.windows.conf
启动redis的客户端:redis-cli
6.执行当前的工程:
进入到爬虫文件对应的目录中:
scrapy runspider xxx.py
7.向调度器队列中仍入一个起始的url
执行了这一步,才会开始爬取内容,要不然一直在等待
队列在redis中,
# 队列名称,前面redis_key = ‘xxx’
lpush fbsQueue www.xxx.com
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider,RedisSpider
from fbsPro.items import FbsproItem
class FbsSpider(RedisCrawlSpider):
name = 'fbs'
# allowed_domains = ['www.xxx.com']
# start_urls = ['http://www.xxx.com/']
#表示的是可被共享调度器中队列的名称
redis_key = 'fbsQueue'
rules = (
Rule(LinkExtractor(allow=r'type=4&page=\d+'), callback='parse_item', follow=True),
)
def parse_item(self, response):
tr_list = response.xpath('//*[@id="morelist"]/div/table[2]//tr/td/table//tr')
for tr in tr_list:
title = tr.xpath('./td[2]/a[2]/@title').extract_first()
status = tr.xpath('./td[3]/span/text()').extract_first()
item = FbsproItem()
item['title'] = title
item['status'] = status
yield item