目录
1. 分布式爬虫原理
2. Scrapy-redis
3. 分布式环境搭建
4. 实战
1. 分布式爬虫原理
分布式爬虫是将多台主机组合起来,共同完成一个爬取任务。
Scrapy单机爬虫中有一个本地爬取队列Queue。如果新的Request生成就会放到Queue里面,随后Request被Scheduler调度。之后,Request交给Downloader执行爬取。
- 单机爬虫:一个Scheduler
- 分布式爬虫:多个Scheduler
维护爬取队列queue:在多台主机上同时运行爬虫任务协同爬取的前提就是共享爬取队列。各台主机不需要各自维护爬取队列,而是从共享爬取队列存取Request。但是各台主机还是有各自的Scheduler和Downloader,所以调度和下载功能分别完成。维护爬取队列首先考虑性能问题,采用基于内存存储的Redis,支持多种数据结构,例如列表(List)、集合(Set)、有序集合(Sorted Set)等,存取的操作也非常简单。
- 去重
Scrapy有自动去重功能,它的去重使用了Python中的集合。这个集合记录了Scrapy中每个Request的指纹,所谓指纹实际上就是Request的散列值。
request_fingerprint()就是计算Request指纹的方法,其方法内部使用的是hashlib的sha1()方法。计算的字段包括Request的Method、URL、Body、Headers这几部分内容,只要这些有一点不同,则计算结果就不同。计算得到的结果是加密后的字符串,也就是指纹。每个Request都有独有的指纹,指纹就是一个字符串,判定字符串是否重复比判定Request对象是否重复容易得多,所以指纹可以作为判定Request是否重复的依据。
对于分布式爬虫来说,要实现去重,指纹集合也需要是共享的,可以利用Redis的集合作为指纹集合。每台主机新生成Request之后,把该Request的指纹与集合比对,如果指纹已经存在,说明该Request是重复的,否则将Request的指纹加入到这个集合中即可。
- 防止中断
单机:
在Scrapy中,爬虫运行时的Request队列放在内存中。爬虫运行中断后,这个队列的空间就被释放,此队列就被销毁了。所以一旦爬虫运行中断,爬虫再次运行就相当于全新的爬取过程。
要做到中断后若想继续爬取,可以将队列中的Request保存到本地,下次爬取直接读取保存的数据即可获取上次爬取的队列。在Scrapy中指定一个爬取队列的存储路径,这个路径使用JOB_DIR变量来标识,可以用如下命令来实现:
crapy crawl spider -s JOB_DIR=crawls/spider
分布式:
在分布式架构中由于爬取队列是用数据库保存的,如果爬虫中断了,数据库中的Request依然是存在的,下次启动就会接着上次中断的地方继续爬取。
所以,当Redis的队列为空时,爬虫会重新爬取;当Redis的队列不为空时,爬虫便会接着上次中断之处继续爬取。
2. Scrapy-redis
scrapy-redis 库已经提供了scrapy 分布式的队列、调度器、去重等功能。
3. 分布式环境搭建
需要一个远程Linux服务器,在服务器上用redis数据库维护共享request队列和指纹集合,各个主机共同访问,在各自机器上运行爬虫程序,将爬取的数据都存到远程服务器的mongodb数据库中。
- 服务器端
1)远程服务器(Linux)
2)安装、配置redis
3)安装、配置mongodb
4)安装Python环境等
- 客户机
1)连接远程服务器的redis数据库
2)连接远程服务器的mongodb数据库
3)安装Python环境,爬虫程序需要的各种库、配置等
- 远程服务器
要实现分布式部署,多台主机需要共享爬取队列和去重集合,而这两部分内容都存于Redis 数据库中,需要搭建一个可公网访问的Redis 服务器。
推荐使用Linux 服务器,可以购买阿里云、腾讯云、Azure 等提供的云主机, 一般都会配有公网IP 。
腾讯云服务器
- 安装、配置redis
安装:
推荐安装宝塔面板——Linux服务器管理软件,他会使我们在服务器上的操作变得简单。
登录CentOS服务器,执行以下命令,安装宝塔面板:
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
安装完成后会出现一个网址 以及用户名和密码,登录该网址,并输入用户名和密码。
在首页/软件商店搜索redis,安装即可。
配置:
点击设置按钮:
在宝塔界面的配置文件(该文件在服务器伤的路径为/www/server/redis/redis.conf)中可以自行修改保存 。服务选项中可以进行重启。修改内容如下
确保可以远程连接:
1)注释 bind 127.0.0.1
2)修改 protected-mode no
设置密码:取消注释 requirepass foobared,foobared 即当前密码,可以自行修改。
重启 redis 服务
在本地测试远程连接服务器:
通过可视化工具rdm连接并查看,远程redis数据库:
1)在Connection中 Host输入本机ip 127.0.0.1 Auth为之前设置的redis密码。
2)在SSH Tunnel中输入远程服务器的ip、端口、密码、用户名:
3)连接成功
- 安装、配置mongodb
安装:
打开宝塔界面, 在首页/软件商店搜索mongodb,安装即可。
配置:
1) 修改配置文件(/www/server/mongodb/config.conf).
找到bindIP将其改成0.0.0.0
修改 authorization: enabled
2) 重启MongoDB
3) 更改防火墙设置
开启27017端口来实现远程访问MongoDB:firewall-cmd --add-port=27017/tcp
4) 添加用户:
切换admin use admin
添加超级用户 db.createUser({user:'root',pwd:'123456',roles:['root']})
MongoDB连接字符串:mongodb://[username:password@]host[:port]
- 安装Python环境
4. 实战
分布式爬取新浪新闻。