要实现分布式爬取,至少需要两台以上的计算机运行爬虫程序,其中一台还需要运行Redis数据库,提供Redis服务。
1、 分布式环境搭建
对于学习者来说,搭建分布式环境最大的问题就是计算机数量不够,解决方法是在一台计算机上安装VMware虚拟机程序,通过VMware创建虚拟机,模拟一台或多台计算机。
使用一台计算机搭建分布式环境:
(1) 在计算机上安装VMware虚拟机程序;
(2) 启动VMware虚拟机,安装Ubuntu操作系统(版本为20.04或更高版本),配置IP地址,模拟一台计算机;
(3) 本机也需要配置IP地址,本机IP地址和虚拟机IP地址要在一个局域网内;
(4) 在虚拟机上安装Redis数据库,作为Redis服务主机;
(5) 在本机和虚拟机上安装Python3.8及其以上版本、Scrapy框架,scrapy-redis组件、部署相同的爬虫代码。
2、 Ubuntu安装Python和Scrapy
检查Python的版本
Ubuntu操作系统已经默认安装了Python,查看Python的安装版本,若版本较低,需要更新Python到3.8或以上版本。
在Ubuntu终端窗口,输入pthon3命令,可以检测是否安装了 Python,以及安装了哪个版本,如下所示:
uroot@userver:~$ python3 Python 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
从输出结果可以看出,本操作系统的Pyhton版本为3.8.5。
安装Scrapy
在Ubuntu终端窗口,输入pip3 install scrapy命令安装Scrapy框架,该命令会自动安装Scrapy框架及其所有的依赖包。
uroot@userver:~$ pip3 install scrapy
安装完成后,在Ubuntu终端窗口会输出下面的结果:
Successfully installed PyDispatcher-2.0.5 cssselect-1.1.0 itemadapter-0.2.0 itemloaders-1.0.4 jmespath-0.10.0 lxml-4.6.2 parsel-1.6.0 protego-0.1.16 queuelib-1.5.0 scrapy-2.4.1 w3lib-1.22.0
3、 创建分布式爬虫项目
分布式环境配置完成后,就可以创建分布式爬虫项目了。我们使用前面百度新闻的爬虫项目,对爬虫项目进行改造,支持分布式爬取。
复制newsbaidu项目到文件夹distribution_newsbaidu,得到newsbaidu项目副本,在项目副本上进行改造。
配置Redis数据库的IP地址和端口
在settings配置文件添加Redis数据库配置项:
# Redis数据库配置项 REDIS_HOST = "192.168.62.190" REDIS_PORT = "6379"
配置项REDIS_HOST配置Redis数据库服务端的IP地址,配置项REDIS_PORT配置Redis数据库的端口。若Redis数据库设置了访问密码,还需要配置访问密码、
REDIS_HOST = "59.110.xxx.xxx"
REDIS_PORT = "6379"
REDIS_PARAMS = {
# 服务器的redis对应密码
'password': 'xxxxx',
}配置scrapy-redis组件
在本机和Ubuntu虚拟机上安装scrapy-redis组件:
pip3 install scrapy-redis
在settings配置文件添加scrapy-redis配置项:
# 使用scrapy_redis的调度器替换Scrapy默认调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 使用scrapy_redis 的RFPDupeFilter作为去重过滤器 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
修改settings配置文件ITEM_PIPELINES配置项,将NewsbaiduPipeMySql管道类替换为RedisPipeline管道类,将爬取数据汇总并存储到Redis数据库:
ITEM_PIPELINES = {
'newsbaidu.pipelines.NewsbaiduPipeline': 300,
'scrapy_redis.pipelines.RedisPipeline': 301,
}单机版爬虫类修改为分布式爬虫类
编辑spider_newsbaidu.py模块文件,将SpiderNewsbaiduSpider爬虫类的基类修改为RedisSpider:
from scrapy_redis.spiders import RedisSpider #class SpiderNewsbaiduSpider(scrapy.Spider): class SpiderNewsbaiduSpider(RedisSpider): …… allowed_domains = ['https://news.baidu.com'] # start_urls = ['https://news.baidu.com/'] ……
在编辑的代码中,可以看到start_urls被注释掉了。这是因为单机版的每个Spider爬虫都会有一个start_urls,在构造起始爬取URL的Request对象时,dont_filter 参数设置为了True,即忽略去重过滤器的过滤。会导致多个(数量等于爬虫数量)重复请求将强行进入Redis 中的请求队列,这可能导致爬取到重复数据。
RedisSpider爬虫类由scrapy-redis组件提供,它重写了start_requests()方法,它会从Redis数据库存储的爬取队列中获取起始爬取URL,并构造Request 对象。
在分布式爬取过程中,所有爬虫运行后,爬取队列是空的,开发者需要使用Reids命令向爬取队列添加起始爬取URL,之后只有其中一个爬虫能获取到起始爬取URL。
爬取起始URL在Redis数据库对应的默认键是<spider_name>:start_urls,该键可通过配置项REDIS_START_URLS_KEY重新设置,一般采用默认键即可。
4、 运行分布式爬虫
将爬虫项目部署到Ubuntu虚拟机,本机已经部署了爬虫项目,至此爬虫项目代码编写及部署已经完成。
项目部署到Ubuntu虚拟机
使用psftp工具将爬虫项目从Windows系统部署到Ubuntu虚拟机,在Windows命令行窗口,将当前目录切换到psftp工具所在目录,运行psftp:
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\PuTTY (64-bit)>psftp psftp: no hostname specified; use "open host.name" to connect psftp> open 192.168.62.190 login as: uroot uroot@192.168.62.190's password: Remote working directory is /home/uroot psftp> put -r D:/splider/distribution_newsbaidu/
psftp的open命令用于连接远程主机,连接成功后会要求输入登录远程主机的账号和密码。
远程主机登录成功后,会显示远程主机当前工作目录,可以使用cd命令切换当前工作目录,或建立一个新的目录用于部署爬虫项目。
使用put命令将爬虫项目整个文件夹传输到远程主机当前工作目录。
本机运行爬虫项目
在Windows命令行窗口,将当前目录切换到项目的根目录,输入下面的命令:
scrapy crawl spider_newsbaidu
本机爬虫运行后,由于Redis数据库中的爬取队列是空的,本机爬虫进入了暂停等待的状态。
2020-12-03 08:57:18 [scrapy.core.engine] INFO: Spider opened 2020-12-03 08:57:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 2020-12-03 08:57:18 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
Ubuntu虚拟机运行爬虫项目
在Ubuntu终端窗口,将当前目录切换到爬虫项目目录:
uroot@userver:~/distribution_newsbaidu/distribution_newsbaidu$
在当前目录输入运行爬虫的命令:
scrapy crawl spider_newsbaidu
爬虫运行后,由于Redis数据库中的爬取队列是空的,爬虫也进入了暂停等待的状态:
2020-12-04 01:10:25 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
设置起始URL到Redis数据库爬取队列
因为Redis数据库的爬取队列是空的,因此本机和虚拟机运行的爬虫都处于等待状态,需要设置起始URL到Redis数据库爬取队列,让爬虫开始工作。
在本机使用Redis客户端设置起始URL到爬取队列,启动Windows命令行窗口,将工作目录切换到Redis安装目录,输入下面的命令连接Redis数据库:
D:\redis>redis-cli.exe -h 192.168.62.190 -p 6379 192.168.62.190:6379>
192.68.62.190是Redis数据库服务器的IP地址,6379是Redis数据库的端口号。
输入下面的命令设置起始URL:
lpush spider_newsbaidu:start_urls 'https://news.baidu.com/'
起始URL设置完成后,观察发现虚拟机上的爬虫首先开始工作,从爬取队列获取了起始URL:
2020-12-04 01:44:45 [spider_newsbaidu] DEBUG: Read 1 requests from 'spider_newsbaidu:start_urls'
随后,本机爬虫也开始工作,等待全部爬取完成后,在Redis中查看爬取到的数据:
192.168.62.190:6379> keys * 1) "spider_newsbaidu:items" 192.168.62.190:6379> LRANGE spider_newsbaidu:items 0 10
上面的命令可以查看爬取的前10条item数据项,每一项数据以json 形式存储在Redis的数据库列表中。若需要使用这些数据,可以编写程序将它们从Redis 数据库中读出。
现在,可以开始你的分布式爬虫项目了。