分布式网络数据抓取系统设计与实现
1、分布式网络数据抓取系统说明
(1)深入分析网络数据(金融、教育、汽车类)爬虫的特点,设计了分布式网络数据(金融、教育、汽车类)系统爬取策略、抓取字段、动态网页抓取方法、分布式结构和数据存储等功能。
(2)简要说明分布式网络数据(金融、教育、汽车类)抓取系统的实现过程。包括爬虫编写、爬虫避禁(各种反爬手段)、动态网页数据抓取、数据存储等内容
(3)对需要爬取的网络数据的网站进行可定制化配置网页模板,进行数据抓取(暂时不考虑界面化)
2、系统功能架构设计
分布式爬虫抓取系统主要包含以下功能:
1.爬虫功能:爬取策略的设计 、内容数据字段的设计、增量爬取、请求去重
2.中间件:反爬机制、ajax动态加载数据、爬虫下载异常处理
3.数据存储:抓取字段设计、数据存储
3、系统分布式架构
分布式采用主从结构设置一个Master服务器和多个Slave服务器,Master端管理Redis数据库和分发下载任务,Slave部署Scrapy爬虫提取网页和解析提取数据,最后将解析的数据存储在同一个MongoDb数据库中。分布式爬虫架构如图所示
应用Redis数据库实现分布式抓取,基本思想是Scrapy爬虫获取的到的detail_request的urls都放到Redis Queue中,所有爬虫也都从指定的Redis Queue中获取requests,Scrapy-Redis组件中默认使用SpiderPriorityQueue来确定url的先后次序,这是由sorted set实现的一种非FIFO、LIFO方式。因此,待爬队列的共享是爬虫可以部署在其他服务器上完成同一个爬取任务的一个关键点。此外,为了解决Scrapy单机局限的问题,Scrapy将结合Scrapy-Redis组件进行开发,Scrapy-Redis总体思路就是这个工程通过重写Scrapy框架中的scheduler和spider类,实现了调度、spider启动和redis的交互。实现新的dupefilter和queue类,达到了判重和调度容器和redis的交互,因为每个主机上的爬虫进程都访问同一个redis数据库,所以调度和判重都统一进行统一管理,达到了分布式爬虫的目的
4、系统实现
4.1、爬取策略的设计
由scrapy的结构分析可知,网络爬虫从初始地址开始,根据spider中定义的目标地址获的正则表达式或者Xpath获得更多的网页链接,并加入到待下载队列当中,进行去重和排序之后,等待调度器的调度。
在这个系统中,新的链接可以分为两类,一类是目录页链接,也就是我们通常看到的下一页的链接,一类是内容详情页链接,也就是我们需要解析网页提取字段的链接,指向的就是实际的页面信息。网络需从每一个目录页链接当中,提取到多个内容页链接,加入到待下载队列准备进一步爬取。爬取流程如下:
此处是Master端的目标链接的爬取策略,因为采取的分布式主从模式,Master端爬虫主要爬取下载到内容详情页链接,通过redis分享下载任务给其他slave端的爬虫。Slave端主要是负责对详情页链接的进一步解析提取存储到数据库中。
1) 对于Master端:
最核心模块是解决翻页问题和获取每一页内容详情页链接。Master端主要采取以下爬取策略:
1. 向redis往key为next_link插入初始链接,从初始页链接开始
2. 爬虫从redis中key为next_link中取到初始链接,开始运行爬虫
3. 将下载器返回的Response,爬虫根据spider定义的爬取规则识别是否有下一页链接,若有链接,存储进redis中,保存key为next_link,同时根据匹配规则是否匹配到多个内容详情页链接,若匹配到,则存储进Redis,保存key为detail_request插入下载链接,给slave端的spider使用,即是Slave端的下载任务。
4. 爬虫继续从redis中key为next_link取值,若有值,继续步骤2,若为空,爬虫则等待新的链接。
2) 对于Slave端:
最核心模块是从redis获得下载任务,解析提取字段。Slave端主要采取以下爬取策略:
1.爬虫从redis中key为detail_request中取到初始链接,开始运行爬虫
2.将下载器返回的Response,爬虫根据spider定义的爬取规则识别是否有匹配规则的内容字段,若有将字段存储,返回到模型中,等待数据存储操作。
重复步骤1,直到带爬取队列为空,爬虫则等待新的链接。
4.2爬虫的具体实现
爬虫程序的包含四个部分,分别是对象定义程序,数据抓取程序,数据处理程序和下载设置程序,此处的组成是Slave端,Master少了对象定义程序以及数据处理程序,Master端主要是下载链接的爬取。
数据抓取程序:
数据抓取程序分Master端和Slave端,数据抓取程序从Redis中获得初始地址,数据抓取程序中定义了抓取网页的规则和使用Xpath提取字段数据的方法、css selector选择器提取数据的方法等
4.3去重与增量爬取
去重与增量爬取,对于服务器有很重大的意义,能够减少服务器的压力以及保证数据的准确性。如果不采取去重处理,那么抓取的内容会抓取大量重复内容,让爬虫效率极大的下降。其实去重流程很简单,核心就是每次请求的时候,先判断这个请求是否在已经爬取的队列当中。如果已存在,则舍弃当前请求。
具体实现步骤:
(1) 从待爬队列中获取url
(2) 将即将请求的url判断是否已经爬取,若已爬取,则将请求忽略,未爬取,继续其他操作并将url插入已爬取队列中
(3) 重复步骤1
4.4爬虫中间件
爬虫中间件能够帮助我们在scrapy抓取流程中自由的扩展自己的程序,以下有爬虫防屏蔽中间件,下载器异常状态中间件以及非200状态中间件。
(1)爬虫防屏蔽组件的实现
访问一个网站的网页的时候,会给网站带了一定的负载,而爬虫程序则是模拟了我们正常访问网页的过程,但是。大规模的爬虫会给网站增加大量的负载,影响正常用户的访问。为保证网页能够别大多数正常用户的访问,大多数网站都有相应的防爬虫策略。一旦访问行为被认定为爬虫,网站将会采取一定的措施,限制你的访问,比如提示你,访问过于频繁让你输入验证码,更严重者,会封掉你的ip,禁止你访问该网站。本系统定向抓取网页数据的时候,将不间断的访问网站内容,如果不采取伪装措施,很容易被网站识别为爬虫行为而屏蔽掉。
本系统采用以下方法来防止爬虫被屏蔽:
1. 模拟不同的浏览器行为
2. 以一定的频率更换代理服务器和网关
3. 降低爬虫爬取网页的频率,减少并发爬取的进程,限制每个ip并发爬取的次数,牺牲一定的效率来换取系统的稳定性。
4. 禁用cookie,网站会在用户访问时在cookie中插入一些信息来判断是否是机器人,我们屏蔽调cookie,也有利于我们的身份不容意暴露。
爬虫防网站屏蔽原理如下图所示:
(a)模拟不同浏览器行为实现思路及代码
原理: scrapy有下载中间件,在这个中间件我们可以对请求跟响应进行自定义处理,核心就是对请求的属性进行修改
首先主要是对下载中间件进行了扩展,首先在seetings.py上面增加中间件,扩展中间件,主要是写一个user-agent列表,将常用的浏览器请求头保存为一个列表,再让请求的头文件随机在列表中取一个agent值,然后到下载器进行下载。
综上,每次发出请求的时候模拟使用不同的浏览器对目标网站进行访问。
(b)使用代理ip进行爬取的实现思路。
首先在settings.py上面增加中间件,扩展下载组件请求的头文件随机从代理ip池中取出一个代理值然后到下载器进行下载。
1. 代理ip池的设计与开发流程如下:
a. 对免费代理ip网站进行抓取。
b. 对代理ip进行存储并验证
c. 验证通过存储进数据库
d.验证不通过的则删除
(c)爬虫异常状态组件的处理
爬虫没有被屏蔽运行时,访问网站不是一直都是200请求成功,而是有各种各样的状态,像上述爬虫被禁的时候,其实返回的状态是302,防止屏蔽组件就是捕捉到302状态加以实现的。同时异常状态的处理有利于爬虫的健壮性。
在settings中扩展中间件捕捉到异常的情况之后,将请求Request重新加入到待下载队列当中流程如下:
(d)数据存储模块
数据存储模块主要负责将slave端爬取解析的页面进行存储。使用Mongodb对数据进行存储。
Scrapy支持数据存储的格式有json,csv和xml等文本格式,用户可以在运行爬虫时设置,例如:scrapy crawl spider
-o items.json -t json,也可以在Scrapy工程文件额ItemPipline文件中定义,同时,Scrapy也支持数据库存储,如Mongodb,Redis等,当数据量大到一定程度时,可以做Mongodb或者Reids的集群来解决问题,本系统数据存储如下图所示:
5.总结
以上就是分布式网络数据抓取系统设计部分,采用分布式的设计是因为单机爬虫的爬取量和爬取速度的局限性,这是V1.0版本,后续将会继续对相关部分进行完善。