一、概念
概念:多台机器对一个项目进行分部联合爬取。
作用:增加工作单位,提升爬取效率。
前提:每一台工作机器都需要scrapy的运行环境。原生的scrapy是不能实现分布式爬虫的,需要结合scrapy-redis
每台机器的scrapy中,如果用各自的调度器,那么就是各自做相同的事情,不是同一个事情,各自使用自己
公用调度器:
1.每台机器都可以进行连接——需要网络服务
2.能够进行数据存储,要爬取的url——数据库
3.队列模型:应该是队列的结构,栈结构且去重唯一 ——Redis列表、集合
可以在Redis中定义一个列表进行存储要爬取的request对象,相当于[start_urls]
环境:
1.scrapy
2.scrapy-redis
Linux只需-pip install scrapy
对公用调度器的要求:1.每台机器都可以进行连接:需要是一个网络服务
2.能够进行存储,要爬取url:数据库
3.队列模型{ mysql:二维表
redis:文档接口{
字符串
列表{LPUSH:
RPUSH:}
哈希
集合:唯一,可实现去重
有序集合
}
mongoDB:json文档
4.去重 }
redis还可以存储item
二、实现流程:准备配置
1.创建项目scrapy startproject distributed
2.创建一个基于CrawlSpider爬虫-可以基于正则匹配url的爬虫
cd distributed
scrapy genspider -t crawl taoche taoche.com
3.settings:(暂不设置日志等级,默认INFO)
基础设置:UA和ROBOTS
4.明确爬取目标——定义item
<以上为scrapy框架的基本步骤,以下为分布式配置>
5.继续配置settings
##############################指定管道####################################
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline':300, #scrapy-redis组件写好了,自动封装Redis数据。多线程的管道
#'distributed.pipelines.DistributedPipeline': 300,
}
###############################指定Redis################################
REDIS_HOST = '127.0.0.1' #本应该是Redis服务器的地址,但现在用的是虚拟机,在本地,写回环地址
REDIS_PORT = 6379 #如果用的VirtualBox,应该是其转发的端口
#去重容器类,作用:用Redis的set集合,来存储请求的指纹数据,从而实现去重和持久化
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
################################使用scrapy-redis的调度器###############################
SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
##############配置调度器是否需要持久化,爬虫结束的时候要不要请客Redis中请求队列和指纹的set集合,要持久化为TRUE
SCHEDULER_PRESIST=True
6.设置Redis(于Linux操作Redis库)
:wq#保存退出
redis-server#重启Redis服务
在redis列表中存储urls:
(py3env) bd@DF:~$ redis-cli
127.0.0.1:6379> LPUSH taoche https://nanjing.taoche.com/bmw/
127.0.0.1:6379> LPUSH taoche https://nanjing.taoche.com/bugatti/
127.0.0.1:6379> LPUSH taoche https://nanjing.taoche.com/mercedesbenz/
127.0.0.1:6379> TYPE taoche
list
127.0.0.1:6379> LLEN taoche
(integer) 4
127.0.0.1:6379> LRANGE taoche 0 -1
1) "https://nanjing.taoche.com/bugatti/"
2) "https://nanjing.taoche.com/porsche/"
3) "https://nanjing.taoche.com/mercedesbenz/"
4) "https://nanjing.taoche.com/bmw/"
三、实现流程:编写爬虫(spiders)
from scrapy_redis.spiders import RedisCrawlSpider
class TaocheSpider(RedisCrawlSpider):#编写的爬虫继承于RedisCrawlSpider
#allowed_domains = ['taoche.com']#注释起来,不做域名限制
#start_urls = ['http://taoche.com/']#起始的urls应该从公共调度器取用(Redis)
redis_key = 'taoche' #会去redis(公共调度器里面获取key为taoche的数据 taoche:[]),相当于strat_urls列表
… …
用两个terminal窗口运行,再打开redis:
127.0.0.1:6379>
(py3env) bd@DF:~$ redis-cli
127.0.0.1:6379> keys *
1) "taoche:items"
2) "taoche:dupefilter"
127.0.0.1:6379> TYPE taoche:dupefilter
set
发现‘taoche’队列没有了,多出来两个新字段
增量式爬虫:检测网站数据的更新情况,只爬取更新的没有爬取过的数据(利用了set集合)。scrapy-redis有这个特性
##############配置调度器是否需要持久化,爬虫结束的时候要不要请客Redis中请求队列和指纹的set集合,要持久化为TRUE
SCHEDULER_PRESIST=True