Python3网络爬虫开发实战
  • Introduction
  • 0-目录
  • 0.0-前言
  • 0.1-序一
  • 0.3-序二
  • 1-开发环境配置
  • 1.1-Python3的安装
  • 1.2-请求库的安装
  • 1.3-解析库的安装
  • 1.4-数据库的安装
  • 1.5-存储库的安装
  • 1.6-Web库的安装
  • 1.7-App爬取相关库的安装
  • 1.8-爬虫框架的安装
  • 1.9-部署相关库的安装
  • 2-爬虫基础
  • 2.1-HTTP基本原理
  • 2.2-Web网页基础
  • 2.3-爬虫基本原理
  • 2.4-会话和Cookies
  • 2.5-代理基本原理
  • 3-基本库的使用
  • 3.1-使用urllib
  • 3.2-使用requests
  • 3.3-正则表达式
  • 3.4-爬取猫眼电影排行
  • 4-解析库的使用
  • 4.1-XPath的使用
  • 4.2-BeautifulSoup的使用
  • 4.3-pyquery的使用
  • 5-数据存储
  • 5.1-文件存储
  • 5.2-关系型数据库存储
  • 5.3-非关系型数据库存储
  • 6-Ajax数据爬取
  • 6.1-什么是Ajax
  • 6.2-Ajax分析方法
  • 6.3-Ajax结果提取
  • 6.4-分析Ajax爬取今日头条街拍美图
  • 7-动态渲染页面抓取
  • 7.1-Selenium的使用
  • 7.2-Splash的使用
  • 7.3-Splash负载均衡配置
  • 7.4-使用Selenium爬取淘宝商品
  • 8-验证码的识别
  • 8.1-图形验证码的识别
  • 8.2-极验滑动验证码识别
  • 8.3-点触验证码识别
  • 8.4-微博宫格验证码识别
  • 9-代理的使用
  • 9.1-代理的设置
  • 9.2-代理池的维护
  • 9.3-付费代理的使用
  • 9.4-ADSL代理的使用
  • 9.5-使用代理爬取微信公众号文章
  • 10-模拟登录
  • 10.1-模拟登录并爬取GitHub
  • 10.2-Cookies池的搭建
  • 11-APP的爬取
  • 11.1-Charles的使用
  • 11.2-mitmproxy的使用
  • 11.3-mitmdump爬取“得到”App电子书信息
  • 11.4-Appium的使用
  • 11.5-Appium爬取微信朋友圈
  • 11.6-Appium+mitmdump爬取京东商品评论
  • 12-pyspider框架的使用
  • 12.1-pyspider框架介绍
  • 12.2-pyspider基本使用
  • 12.3-pyspider用法详解
  • 13-Scrapy框架的使用
  • 13.1-Scrapy框架介绍
  • 13.2-Scrapy入门
  • 13.3-Selector的用法
  • 13.4-Spider的用法
  • 13.5-Downloader Middleware的用法
  • 13.6-Spider Middleware的用法
  • 13.7-Item Pipeline的用法
  • 13.8-Scrapy对接Selenium
  • 13.9-Scrapy对接Splash
  • 13.10-Scrapy通用爬虫
  • 13.11-Scrapyrt的使用
  • 13.12-Scrapy对接Docker
  • 13.13-Scrapy爬取新浪微博
  • 14-分布式爬虫
  • 14.1-分布式爬虫理念
  • 14.2-Scrapy-Redis源码解析
  • 14.3-Scrapy分布式实现
  • 14.4-Bloom Filter的对接
  • 15-分布式爬虫的部署
  • 15.1-Scrapyd分布式部署
  • 15.2-Scrapyd-Client的使用
  • 15.3-Scrapyd对接Docker
  • 15.4-Scrapyd批量部署
  • 15.5-Gerapy分布式管理
Powered by GitBook
On this page
  • 1. 准备工作
  • 2. 搭建 Redis 服务器
  • 3. 部署代理池和 Cookies 池
  • 4. 配置 Scrapy-Redis
  • 核心配置
  • Redis 连接配置
  • 配置调度队列
  • 配置持久化
  • 配置重爬
  • Pipeline 配置
  • 5. 配置存储目标
  • 6. 运行
  • 7. 结果
  • 8. 本节代码
  • 9. 结语

Was this helpful?

14.3-Scrapy分布式实现

Previous14.2-Scrapy-Redis源码解析Next14.4-Bloom Filter的对接

Last updated 5 years ago

Was this helpful?

接下来,我们会利用 Scrapy-Redis 来实现分布式的对接。

1. 准备工作

请确保已经成功实现了 Scrapy 新浪微博爬虫,Scrapy-Redis 库已经正确安装,如果还没安装,请参考第 1 章的安装说明。

2. 搭建 Redis 服务器

要实现分布式部署,多台主机需要共享爬取队列和去重集合,而这两部分内容都是存于 Redis 数据库中的,我们需要搭建一个可公网访问的 Redis 服务器。

推荐使用 Linux 服务器,可以购买阿里云、腾讯云、Azure 等提供的云主机,一般都会配有公网 IP,具体的搭建方式可以参考第 1 章中 Redis 数据库的安装方式。

Redis 安装完成之后就可以远程连接了,注意部分商家(如阿里云、腾讯云)的服务器需要配置安全组放通 Redis 运行端口才可以远程访问。如果遇到不能远程连接的问题,可以排查安全组的设置。

需要记录 Redis 的运行 IP、端口、地址,供后面配置分布式爬虫使用。当前配置好的 Redis 的 IP 为服务器的 IP 120.27.34.25,端口为默认的 6379,密码为 foobared。

3. 部署代理池和 Cookies 池

新浪微博项目需要用到代理池和 Cookies 池,而之前我们的代理池和 Cookies 池都是在本地运行的。所以我们需要将二者放到可以被公网访问的服务器上运行,将代码上传到服务器,修改 Redis 的连接信息配置,用同样的方式运行代理池和 Cookies 池。

远程访问代理池和 Cookies 池提供的接口,来获取随机代理和 Cookies。如果不能远程访问,先确保其在 0.0.0.0 这个 Host 上运行,再检查安全组的配置。

如我当前配置好的代理池和 Cookies 池的运行 IP 都是服务器的 IP,120.27.34.25,端口分别为 5555 和 5556,如图 14-3 和图 14-4 所示。

图 14-3 代理池接口

图 14-4 Cookies 池接口

所以接下来我们就需要把 Scrapy 新浪微博项目中的访问链接修改如下:

PROXY_URL = 'http://120.27.34.25:5555/random'
COOKIES_URL = 'http://120.27.34.25:5556/weibo/random'

具体的修改方式根据实际配置的 IP 和端口做相应调整。

4. 配置 Scrapy-Redis

配置 Scrapy-Redis 非常简单,只需要修改一下 settings.py 配置文件即可。

核心配置

首先最主要的是,需要将调度器的类和去重的类替换为 Scrapy-Redis 提供的类,在 settings.py 里面添加如下配置即可:

SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

Redis 连接配置

接下来配置 Redis 的连接信息,这里有两种配置方式。

第一种方式是通过连接字符串配置。我们可以用 Redis 的地址、端口、密码来构造一个 Redis 连接字符串,支持的连接形式如下所示:

redis://[:password]@host:port/db
rediss://[:password]@host:port/db
unix://[:password]@/path/to/socket.sock?db=db

password 是密码,比如要以冒号开头,中括号代表此选项可有可无,host 是 Redis 的地址,port 是运行端口,db 是数据库代号,其值默认是 0。

根据上文中提到我的 Redis 连接信息,构造这个 Redis 的连接字符串如下所示:

redis://:foobared@120.27.34.25:6379

直接在 settings.py 里面配置为 REDIS_URL 变量即可:

REDIS_URL = 'redis://:foobared@120.27.34.25:6379'

第二种配置方式是分项单独配置。这个配置就更加直观明了,如根据我的 Redis 连接信息,可以在 settings.py 中配置如下代码:

REDIS_HOST = '120.27.34.25'
REDIS_PORT = 6379
REDIS_PASSWORD = 'foobared'

这段代码分开配置了 Redis 的地址、端口和密码。

注意,如果配置了 REDIS_URL,那么 Scrapy-Redis 将优先使用 REDIS_URL 连接,会覆盖上面的三项配置。如果想要分项单独配置的话,请不要配置 REDIS_URL。

在本项目中,我选择的是配置 REDIS_URL。

配置调度队列

此项配置是可选的,默认使用 PriorityQueue。如果想要更改配置,可以配置 SCHEDULER_QUEUE_CLASS 变量,如下所示:

SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.LifoQueue'

以上三行任选其一配置,即可切换爬取队列的存储方式。

在本项目中不进行任何配置,我们使用默认配置。

配置持久化

此配置是可选的,默认是 False。Scrapy-Redis 默认会在爬取全部完成后清空爬取队列和去重指纹集合。

如果不想自动清空爬取队列和去重指纹集合,可以增加如下配置:

SCHEDULER_PERSIST = True

将 SCHEDULER_PERSIST 设置为 True 之后,爬取队列和去重指纹集合不会在爬取完成后自动清空,如果不配置,默认是 False,即自动清空。

值得注意的是,如果强制中断爬虫的运行,爬取队列和去重指纹集合是不会自动清空的。

在本项目中不进行任何配置,我们使用默认配置。

配置重爬

此配置是可选的,默认是 False。如果配置了持久化或者强制中断了爬虫,那么爬取队列和指纹集合不会被清空,爬虫重新启动之后就会接着上次爬取。如果想重新爬取,我们可以配置重爬的选项:

SCHEDULER_FLUSH_ON_START = True

这样将 SCHEDULER_FLUSH_ON_START 设置为 True 之后,爬虫每次启动时,爬取队列和指纹集合都会清空。所以要做分布式爬取,我们必须保证只能清空一次,否则每个爬虫任务在启动时都清空一次,就会把之前的爬取队列清空,势必会影响分布式爬取。

注意,此配置在单机爬取的时候比较方便,分布式爬取不常用此配置。

在本项目中不进行任何配置,我们使用默认配置。

Pipeline 配置

此配置是可选的,默认不启动 Pipeline。Scrapy-Redis 实现了一个存储到 Redis 的 Item Pipeline,启用了这个 Pipeline 的话,爬虫会把生成的 Item 存储到 Redis 数据库中。在数据量比较大的情况下,我们一般不会这么做。因为 Redis 是基于内存的,我们利用的是它处理速度快的特性,用它来做存储未免太浪费了,配置如下:

ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 300}

本项目不进行任何配置,即不启动 Pipeline。

到此为止,Scrapy-Redis 的配置就完成了。有的选项我们没有配置,但是这些配置在其他 Scrapy 项目中可能用到,要根据具体情况而定。

5. 配置存储目标

之前 Scrapy 新浪微博爬虫项目使用的存储是 MongoDB,而且 MongoDB 是本地运行的,即连接的是 localhost。但是,当爬虫程序分发到各台主机运行的时候,爬虫就会连接各自的的 MongoDB。所以我们需要在各台主机上都安装 MongoDB,这样有两个缺点:一是搭建 MongoDB 环境比较烦琐;二是这样各台主机的爬虫会把爬取结果分散存到各自主机上,不方便统一管理。

所以我们最好将存储目标存到同一个地方,例如都存到同一个 MongoDB 数据库中。我们可以在服务器上搭建一个 MongoDB 服务,或者直接购买 MongoDB 数据存储服务。

这里使用的就是服务器上搭建的的 MongoDB 服务,IP 仍然为 120.27.34.25,用户名为 admin,密码为 admin123。

修改配置 MONGO_URI 为如下:

MONGO_URI = 'mongodb://admin:admin123@120.27.34.25:27017'

到此为止,我们就成功完成了 Scrapy 分布式爬虫的配置了。

6. 运行

接下来将代码部署到各台主机上,记得每台主机都需要配好对应的 Python 环境。

每台主机上都执行如下命令,即可启动爬取:

scrapy crawl weibocn

每台主机启动了此命令之后,就会从配置的 Redis 数据库中调度 Request,做到爬取队列共享和指纹集合共享。同时每台主机占用各自的带宽和处理器,不会互相影响,爬取效率成倍提高。

7. 结果

一段时间后,我们可以用 RedisDesktop 观察远程 Redis 数据库的信息。这里会出现两个 Key:一个叫作 weibocn:dupefilter,用来储存指纹;另一个叫作 weibocn:requests,即爬取队列,如图 14-5 和图 14-6 所示。

图 14-5 去重指纹

图 14-6 爬取队列

随着时间的推移,指纹集合会不断增长,爬取队列会动态变化,爬取的数据也会被储存到 MongoDB 数据库中。

至此 Scrapy 分布式的配置已全部完成。

8. 本节代码

9. 结语

本节通过对接 Scrapy-Redis 成功实现了分布式爬虫,但是部署还是有很多不方便的地方。另外,如果爬取量特别大的话,Redis 的内存也是个问题。在后文我们会继续了解相关优化方案。

本节代码地址为:,注意这里是 distributed 分支。

https://github.com/Python3WebSpider/Weibo/tree/distributed