大规模异步新闻爬虫的分布式实现

Python爬虫 2019-06-10 17:24:37 阅读(10043) 评论(2)

前面我们讲了《大规模异步新闻爬虫的实现思路》,在文章最后提到了把它升级为分布式的思路。今天,我们就来详细实现一下,把它真正升级为分布式的大规模异步爬虫。

大规模异步新闻爬虫的分布式实现

一、架构

我们设计的这个分布式是典型的CS架构,也就是分为服务器端和客户端。服务器端我们称为“爬虫Server”,客户端称为“爬虫Client”。

爬虫Server,负责管理所有URL(即,爬虫客户端的下载任务)的状态,通过我们前面介绍的UrlPool(网址池)进行管理。还不知道UrlPool的同学可以搜索我们前面的文章,或者到《猿人学网站》上去看“Python爬虫教程”找到UrlPool的讲解。Server提供接口给Clients,以便它们获取URL和提交URL。

爬虫Client,负责URL的下载、网页的解析以及存储等各种。Client通过接口向Server请求需要被下载的URL,下载完成后向Server报告URL是否下载成功,同时把从网页中提取到的URLs提交给Server,Server把它们放入URLPool。

Server和Client的分工明确,由它们组成的分布式爬虫的架构就是这样子的:

分布式爬虫设计图

我们把这个分布式爬虫叫做“bee”(小蜜蜂),寓意一群蜜蜂去采蜜。分别创建Server和Client的文件:

bee_server.py

bee_client.py

 

二、爬虫Server端实现

爬虫Server端需要建立一个服务,它可以是TCP的,也可以是HTTP的。这里,我们选择Python的异步web框架:Sanic 来写这个服务。这个服务很简单,代码如下:

用sanic做服务端

上面是web服务的实现代码,通过

@app.listener(‘after_server_stop’)

在Server退出前,缓存URLPool里面的url。

整个web服务就实现了一个接口:/task, 通过GET方法让client获取URLs,通过POST让client提交URLs。

后面再加上执行程序:

分布式服务端程序入口

 

三、爬虫Client的实现

我们把Client写成一个类,这个类一部分接口是与Server交互用的,也就是从Server那里获取要下载的URL,以及向Server提交新得到的URLs。另外一部分接口是与互联网交互的,即下载URLs。

通过异步IO,我们可以把Client的并发提高上去,达到更高的抓取速度。

先来看看这个类的初始化:

分布式爬虫客户端设计

其中,self._workers 记录当前正在下载的协程(即,并发数);

sellf.workers_max 是限制最大并发数,根据自己的CPU性能和网络带宽调整其大小,从而达到最大效率利用硬件资源。

download()方法是对aiohttp的封装,方便异步下载。

下面是与Server服务进行交互的两个方法:

分布式爬虫服务端和客户端交互

下面是下载任务相关的方法。其中save_html()根据自己需要可以把下载的网页保存到数据库;filter_good()清洗提取到的URLs,把不需要下载的URLs扔掉。process()是个协程定义,它的工作就是下载、提取、保存、提交,这个协程会在抓取循环中被不断的创建,达到并发的目的。

服务端处理html的方式

最后,我们定义两个循环,一个用于定时向Server请求要下载的URLs,另一个用于调度下载任务处理协程。通过self._workers这个计数器限制协程数量。start()方法就是整个类的执行入口。

用协程来提高服务端的处理能力

最后的最后,我们需要执行Client:

新闻爬虫客户端的入口

 

四、运行和部署

运行过程很简单,先运行Server程序:bee_server.py

运行分布式爬虫的服务端

再运行Client程序: bee_client.py

运行分布式爬虫的客服端

部署的话,可以单机也可以多机。

如果你的服务器很强,多核的,单机可能就满足你的下载量的需求了。首先运行一个Server,剩下client的运行数量根据核数来定。单核大约占50%的CPU,自己多跑跑看。

如果你的下载量很大,比如实时抓取几千家新闻网站,那么可以多台、多核进行部署。这时候,记得改一下Server监听的host为0.0.0.0,以便其它机器能访问它。

这就是一个分布式的爬虫,道理很简单,实现也不复杂。由于UrlPool的支持,你的Server可以随时停掉重启,然后继续无重复下载。在这套代码上面,修改部分接口,就可以实现你自己的抓取目的。

老规矩,猿人学Python公众号后台回复“bee”获取相关代码。

———————————–

广而告之,最近我在教爬虫

一对一教学Python爬虫;

学会如何设计抓取海量数据的爬虫;

学会如何分析/反反爬策略;

学完自己能真实动手开发那种;

在猿人学Python公众号菜单栏-联系我,找到我的微信。

 

爬虫文章拓展阅读:

如何让爬虫一天抓取100万张网页

大规模异步新闻爬虫的实现思路

逆向js加密,代码混淆不是难事

爬虫小偏方:robots.txt快速抓取网站的小窍门

爬虫挣钱系列-(完结篇)结构化人名挣钱第三篇

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...

  1. 1楼
    注子 5年前 (2020-04-26)

    您好,server程序运行在自己电脑上,client程序在自己买的云服务器上,这样理解对吗?

    • 回复
      王平 5年前 (2020-04-28)
      回复 @注子 :server端肯定在服务器嘛