Logo

郎哥编程

分布式爬取案例

2020-12-26 218

要实现分布式爬取,至少需要两台以上的计算机运行爬虫程序,其中一台还需要运行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 数据库中读出。

现在,可以开始你的分布式爬虫项目了。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论