通用爬虫框架
如下图是一个通用的爬虫框架流程。
首先从互联网页面中选择一部分网页,以这些网页的链接地址作为种子URL,将这些种子URL 放入待抓取的URL队列中,爬虫从待抓取的URL队列中一次读入,并将URL通过DNS解析,把链接地址转换为网站服务器对应的IP地址。然后将IP和对应的网页相对路径名称交给网页下载器,网页下载器负责页面内容的下载。
对于下载到本地的网页,一方面将其存储到页面库中,等待建立索引等后续处理;另一方面将下载网页的URL 放入已抓取的URL队列中,这个队列是为了避免重复抓取。对于刚下载的网页,从中抽取出所包含的所有链接信息,并在已抓取的URL队列中检查,如果没有被抓取过则放入待抓取的URL队列中。
如此循环直到待抓取URL为空。
当然还有网页去重和反作弊等,后面会专门讲解,在上面的内容中未列出。
- 互联网页面划分
- 已下载网页集合
- 已过期网页集合:由于爬虫完整抓取需要较长时间,在这个动态过程中,会出现本地内容和互联网内容不一致的情况。
- 待下载网页集合
- 可知网页集合:这类网页还没有被爬虫下载,也没有出现在待抓取URL队列中。
- 不可知网页集合:对于爬虫来说无法抓取到。事实上这部分的比率很大。
- 爬虫类型划分
- 批量型爬虫:有明确的抓取范围和目标,当达到该目标后,停止抓取。
- 增量型爬虫:会保持不断的抓取,要定期更新。(通用的商用搜索引擎爬虫都属于这类)
- 垂直型爬虫:关注特定的主题内容。该爬虫的难点是如何识别是否是指定主题的内容。
优秀爬虫的特性包括:
- 高性能
- 可扩展性(分布式)
- 健壮性:对于可能遇到的非正常情况,比如HTML编码不规范或者抓取的服务器死机或者爬虫陷阱等等。
- 友好性
爬虫禁抓协议(Robot Exclusion Protocol)指的是网站所有者生成的一个指定文件:robot.txt,并放在网站服务器的根目录下,该文件指明了网站哪些目录下的网页是不允许爬虫抓取的。
如果想让单个网页不被抓取,使用网页禁抓标记(Robot META tag)。比如:<meta name="robots" content="noindex">
:禁止索引网页内容,<meta name="robots" content="nofollow">
:禁止抓取网页链接。
抓取策略
- 宽度优先遍历策略(Breath First)
使用队列很明显就使用了宽搜,将新抓取的URL放在队列尾部。
- 非完全PageRank策略
PageRank是一种著名的链接分析算法,可以用来衡量网页的重要性(技术细节以后再说)。很自然的可以用PageRank的思想对URL的优先级进行排序。然而由于PageRank是一个全局性的算法,也就是说当所有网页都下载完成后,其计算结果才是可靠的,而爬虫的目的就是去下载网页。
所以只有使用非完全的PageRank,对于已经下载的网页,加上待抓取的URL队列一起,形成网页集合,在此集合内进行PageRank的计算,计算完成后,待抓取的URL按照PageRank得分排序。
然而不可能每次抓到一个新的URL,就计算一次PageRank值,所以一个折中的办法是:没当下载的网页攒够K个,才进行一遍。然而,还有一个问题,如果当前URL很重要(比如从新下载的网页中抽取出的新链接很重要),但是还没到进行PageRank的时候,怎么做呢?设置一个临时PageRank值即可,如果这个值比待抓取的队列中已经计算的PageRank值高,那么先下载它。
- OCIP策略(Online Page Importance Computation)
在线页面重要性计算,可以看做一种改进的PageRank算法。
在算法开始之前,每个页面都给予相同的cash,当下载了某页面后,把cash分配给页面中包含的链接的页面,则对于待抓取的队列,优先级取决于cash的多少。OCIP不需要像PageRank一样迭代。
- 大站优先策略
待抓取URL队列中的网页以其所属网页进行归类,如果哪个网站等待下载的最多,则优先下载这些链接。
网页更新策略
- 历史参考策略
对于过去频繁更新的网页,将来也会频繁更新。一般利用泊松过程对网页的变化进行建模。
- 用户体验策略
用户一般只查看搜索前3页的内容,所以一般没必要太快更新看不到的内容。
- 聚类抽样策略
上面两种方法都依赖网页的历史更新信息。但是在现实中,为每个网页保留历史更新信息会使得搜索系统增加大量的负担。
聚类抽样策略认为:网站有一些属性,这些属性可以预测更新周期。
暗网抓取
很多网站的内容是以数据库的方式存储的,典型例子就是一些垂直领域的网站,比如携程的机票数据,很难有显示的链接指向数据库内的记录,往往是通过网站上的查询完成的。所以,常规的爬虫无法索引这些内容。
为了能对暗网数据进行索引,需要研发与常规爬虫机制不同的系统,这类爬虫被称为暗网爬虫,其目的是将暗网数据从数据库中挖掘出来,并将其假如搜索引擎进行索引。
- 查询组合问题
垂直搜索网站往往会给用户提供多个查询输入框,不同输入框代表了搜索对象某方面的属性。对于暗网爬虫来说,一种简单粗暴的方式就是把所有可能的属性组合(即查询的输入)都完成一遍。但是,这样很多组合是无效的,而且不友好。
Google对此的解决方案是:富含信息查询模版。
譬如,一个职位的查询由3个属性构成:职位类别、行业类别和工作地点。如果在查询的时候,部分属性被赋值,而其他属性不赋值,这几个赋值的属性就称为查询模版。
对于垂直搜索来说,其查询模版组合起来有很多,我们的任务是找到富含信息的查询模版。那么怎么称为富含信息呢?如果给模版内的每个属性都赋值,形成不同的组合,提交给垂直搜索引擎,观察所返回的内容,如果相互之间内容差异大,那么这个查询模版就是富含信息的。
譬如模版:Http://www.xxx.com/query?职位类别=人力资源&行业类别=不限&工作地点=北京
。其中包含了两个属性:职位类别、工作地点,职位类别有3种赋值,工作地点有10种赋值,那么两者就有30种赋值,那么将这30种查询分别提交给搜索引擎,看看页面内容变化,如果大部分都相似,那么这个查询模版不是富含信息的查询模版。
上面的方法查询模版可能有很多种,如果一一试探,系统效率还是很低。为了进一步减少提交的查询数目,Google的技术方案使用了ISIT算法。
ISIT算法的基本思路是:首先从一维模版(只有一个属性的模版)开始,对一维模版进行逐个考差,看其是否富含信息查询模版,如果是的话,则将这个一维模版扩展到二维,再逐个考察。也就是从一维到二维再到N维的一个形式。
- 文本框填写问题
对于输入中的文本框,需要爬虫自动生成查询。
同样需要一些初始的种子查询关键词表。对于不同的网站,需要人工提供不同的此表,以此作为爬虫能够继续工作的基础条件。
根据这个种子查询关键词表,向垂直搜索引擎提交查询,并下载返回的结果页面。然后从结果页面中自动挖掘出相关的关键词,并形成一个新的查询。
分布式爬虫
对于商业搜索引擎来说,分布式是必须采用的技术。一般包含了:分布式数据中心、分布式抓取服务器、分布式爬虫程序。每个数据中心负责抓取本地域周边的互联网网页,比如欧洲的数据中心会抓取英国、法国、德国等欧洲国家的网页。每个数据中心由多台抓取服务器构成,而每台服务器又可以部署多个爬虫程序。通过多层级的分布式爬虫体系,才可以保证抓取数据的及时性和全面性。
一般爬虫的分布式架构有两种:
- 主从:其中一台负责URL的分发。因为URL分发服务的服务器会承担管理任务,同时待抓取的URL队列数量巨大,所以URL服务器容易成为整个系统的瓶颈。
- 对等:不存在分工差异,而由于没有URL服务器存在,抓取服务器的分工就成了问题。如何判断某个URL由谁抓取:一般是对网址的主域名进行Hash计算然后取模,对应的模分配给对应编号的服务器。缺点是:如果发生宕机,任务需要重新分配(可由一致性哈希算法解决,这里不做介绍)。