网页搜集系统

自1994年万维网出现后,互联网上的网页数量就呈指数级生长,到目前为止,短短二十余年,互联网上就有成百上千亿网页。如何在这海量的网页中搜索下载具备对特定场景有价值的网页?使用什么样的策略能保证网页不会出现重复?如何保证爬虫程序的高并发爬取?如何在网页中提取关键点等等问题,这是本篇博客重点描述的内容。php

1.1 万维网结构分析

把万维网看做是一个相互连通的连通图,每一个网页看做一个节点,连接看做为边,其中任意一个网页可被其它网页所连接,这种连接叫“反向连接”,这个网页也能够连接到其它网页,这种连接就叫“正向连接”。遍历网页的有两种方向,正向遍历和反向遍历,其中正向遍历是按正向连接的方向进行遍历网页,而反向遍历则是按反向连接的方向遍历网页。html

研究者经实验发现,不管是正向遍历仍是反向遍历,表现出来的是大相径庭的效果。要么遍历到不多的一个网页集合,要么是爆炸性的遍历到上亿的网页,从实验结果中,研究者发现,万维网具备蝴蝶结型结构,以下图所示。nginx

图 1-1万维网的蝴蝶结型结构[1]算法

此结构分为左中右三部分,其中左部的成为“目录型网页”,即常说的导航网页,今后部分出发开始采用正向遍历,可至少能遍历到所有网页的3/4,而采用反向遍历,则只能遍历到不多的一部分;中部的网页则是彼此连通的网页,此部分无论是采用正向仍是反向,都大体可遍历到所有网页的3/4;右部的网页称为“权威网页”,这部分网页被中部网页所指向,这部分的网页“承认度”高,被大部分网页所引用,很明显,此部分网页的遍历与左部网页的遍历呈对称型;而“蝴蝶”的“须脚”部分,此部分的网页表现为从左部连接到其它网页,或者从左部或右部直接连接到右部,以及少部分与中部、左部或右部都没有连接,在此部分网页出发,无论采用正向遍历或是反向遍历都只能遍历到有限的不多一部分网页。sql

通过以上分析,咱们能够得出,爬虫应尽量从蝴蝶型的左部出发,或从中部的网页开始遍历。数据库

1.2 网络爬虫

网络爬虫是网页搜集系统最重要的一部分之一,它是搜索引擎工做的基础。本节中将介绍网络爬虫的基础概念、分布式爬虫的架构、一些爬取网页的策略以及robots协议等。数组

1.2.1 爬虫概念

爬虫,它经过下载一个网页,分析其中的连接,继而去访问其它连接指向的网页,周而复始进行,直到磁盘满或人工干预,爬虫的功能归结为两点:下载网页和发现URL。浏览器

爬虫访问网页和浏览器有着相同的方式,一样也都是都是使用HTTP协议和网页服务器交互。流程主要以下[2]缓存

1.   客户端程序(爬虫程序)链接到一个DNS服务器上。DNS服务器将主机名转换呈IP地址,由于爬虫程序会频繁的查询DNS服务器,因此可能会形成相似于拒绝服务攻击(DOS)的反作用,因此在不少爬虫程序实现中都会增长DNS缓存,以减小不少没必要要的DNS服务器查询,在商业搜索引擎中,通常都会搭建本身的DNS服务器。
2.   创建链接后,客户端会发送一个HTTP请求给网络服务器,以请求一个页面。常见的HTTP请求是GET请求,如:
GET http://www.sina.com.cn/index.htmlHTTP/1.1
该命令表示请求服务器使用HTTP 1.1协议规范1.1版本,将页面www.sina.com.cn/index.html页面返回给客户端。固然客户端也可以使用POST命令访问网络服务器。一样,爬虫程序也会频繁的使用GET命令,而使用该命令后会将页面全部内容返回给客户端,在网页重访(由于不少网页会更新,因此需重访网页以获得最新的网页内容)时,尝试用HEAD命令访问服务器,该命令则是要求将网页的head部分返回给客户端,该head部分包含了网页的最后更新时间(Last-Modified)字段,在比对数据库中该网页的此字段后,就可避免大量未更新网页的下载。
3.   分析网页中的URL连接,将它们插入一个队列中,同时提取网页中的重要内容存储到数据库中。队列的主要特色是FIFO,每次将新发现的URL插到队列尾部,而后取得从队列头部取得下一待访问URL,这样循环反复进行,直到队列为空,这即是常说的宽度优先遍历。

通过以上三个步骤便实现了一个简单的网络爬虫。但其中还有不少问题,例如:服务器

1)  如何避免访问重复URL(访问重复URL将会致使无限循环);

2)  爬虫需遵循的Robots协议等;

3)  如何避免因频繁的访问致使网络服务器“发怒”;

4)  如何设计本课题中电子产品页面采集策略;

5)  分类器;

6)  网页格式的转换问题;

7)  如何设计网页的存储结构以及选择什么样的数据库存储海量网页页面;

8)  由于网页也会由于过时,如何设计重访网页策略;

9)  如何高效率地爬取网页(将在1.3节中讲解);

URL重复避免

避免URL重访是一个很关键的问题,若是URL重复访问,必然会致使一个无限的递归访问,直至资源穷尽。通常的策略是维护两个表:visited_table和unvisited_table,visited_table表示已访问URL的表,而unvisited_table至关于一个“任务池”,爬虫不断地从unvisited_table中取得待访问URL,这样就避免了网页的重复访问。工做步骤以下:

1.   为爬虫线程添加一个control进程,此进程主要功能是控制爬虫爬取网页,维护两个URL表等,至关于一个控制器。

2.   爬虫每次爬取网页时,从unvisited_table中取得URL,下载网页后,对网页进行一系列处理插入到数据库中,同时分析网页中的连接,将连接递交到control进程。

3.   control进程在获得爬虫URL连接后,比对visited_table,看其中是否存在,若不存在,则将该URL插入到unvisited_table中,同时会返回一个URL给爬虫,爬虫继续爬取该URL。

visited_table可以使用一个hash函数,则visited_table是一个bit数组。由于hash函数面临着冲突问题,因此若是有更高的精确要求,可改用Bloom Filter,Bloom Filter的原理很简单,它使用多个不一样hash函数来断定,例如,初始化bit数组全部位为0,对于一个URL1,使用多个不一样的hash函数计算后,将bit数组相应位置1,当判断URL2是否已访问时,对URL2一样使用hash函数计算,若是计算后,相应的bit数组为0,则表示该URL未访问,不然,若bit数组中其中任何一位为1,则表示该URL已访问, 具体的证实可参考参考文献。


图1-2 Bloom Filter工做原理示例图

正如图1-2所示,对URL2使用Bloom Filter时,有一个bit位已置1,故表示该URL已访问过。


避免网络服务器“发怒”

为什么网络服务器会“发怒”?网络服务器承受不住爬虫的频繁快速的访问,若是该网络服务器性能不是很强大,它将花费全部时间处理网络爬虫的请求,而不会去处理真实用户的请求,因而它可能将该爬虫看做是DOS攻击,从而禁止爬虫的IP,因此应该避免网络服务器的“发怒”,如何处理呢?一般是在爬虫访问该服务器后,爬虫应该等待几秒,从而给网络服务器足够的时间去处理其它请求,同时爬虫也应该遵照robots协议。

robots协议

robots协议是Web站点和搜索引擎爬虫交互的一种方式,网络管理员将一个robots.txt的文件放在网站的根目录上,例如https://www.google.com/robots.txt.


其中User-agent表示爬虫类型(如上图中的*表示全部爬虫),Disallow表示禁止该爬虫爬取的目录,Allow表示容许爬取的页面或目录,因此在具体实现搜索引擎时,还应该增长一个robots协议分析模块,严格遵照robots协议的规定只抓取Web主机容许访问的目录和网页。

 

页面采集策略

针对垂直搜索策略有如下两种:

1.   对整个互联网页面搜集下载,而后去除不相关页面。此种方法的缺点是将会占用大量的磁盘空间和带宽,在具体实现中不可取。

2.   第二种方式是基于这样一个事实:一个话题页面每每存在相关主题页面。其中锚文本的做用相当重要,它指示了相关连接的主题,因此在实际应用中,一个特定话题的多个权威页面都被用做种子页面。

文本分类技术。爬虫使用分类器来肯定该页面是否与给定的主题相关。经常使用朴素贝叶斯分类器或支持向量机等。下面将简要讲解这两种分类器。

分类器

1.   朴素贝叶斯分类器

 

2.   支持向量机

 

网页格式转换

计算机中文本是以几百种相互之间不兼容的格式进行存储的。标准的文本格式包括原始文本、HTML、XML、Word以及PDF等等,若是不以正确的方式去处理,每每会出现乱码的状况,因此须要一个工具,在处理到一个新文本格式时,能将它转换成通用的格式,在本课题中,则将它转换到HTML格式便可。计算机存储文件时,还有个问题是编码问题,此问题的通用解决方案是查看网页头部的编码格式,而后以相应的编码格式读取分析。

因此,当下载到一篇网页后,首先查看头部信息:查看文本格式和编码格式,而后以相应的方法去处理便可。

网页存储问题

网页的存储面临两个问题:以什么样的格式存储网页?使用什么样的数据库?

1.   首先处理存储网页的格式问题。若是将下载后的网页直接存储到数据库,则有两个问题:

1)  每一个网页平均约有70K,在磁盘上传输70K的数据会很快,可能只须要不到1毫秒的时间,但在查找时,却可能须要10毫秒,因此在打开这些零散小文件来读取文档时,需大量的时间开销,一种好的解决方案是将多个文档存储在一个单独的文件中,以一种自自定义的格式进行存储,例如:

<DOC>
<DOCNO>102933432<DOCNO>
<DOCHEADER>
http://www.sina.com.cn/index.htmltext/html 440
http/1.1200 ok
IP:221.236.31.210
Date:Wed, 02 Jan 2016 09:32:23 GMT
Content-Encoding: gzip
Last-Modified: Tue, 03 Jan 2016 01:52:09GMT
Server: nginx
Content-Length: 119201
</DOCHEADER>
<!DOCTYPE html>
<html>
<head>
   <meta http-equiv="Content-type" content="text/html;charset=utf-8" />
   <meta http-equiv="X-UA-Compatible"content="IE=edge" />
             <title>新浪首页</title>
……
</html>
</DOC>
<DOC>
<DOCNO>102933433<DOCNO>
<DOCHEADER>
……
</DOCHEADER>
……
</DOC>


例子中:

<DOC></DOC>标记了一篇网页的内容,其中包括了<DOCNO>、<DOCHEADER>和网页原始内容;<DOCNO></DOCNO>标记网页的编号;,<DOCHEADER></DOCHEADER>标记了网页的头部信息,此部分大多数由网络服务器返回;剩余部分为网页内容。

2) 若是数据量过大,经常会将存储的文件进行压缩以节省磁盘空间。

2. 第二个问题是存储系统的选择。存储系统能够选择关系数据库和NoSQL数据库,在主要的搜索引擎中,不多使用传统的关系数据库来存储文档,由于大量的文档数据将会压垮关系数据库系统,非关系数据库的强大分布式能力,海量数据存储能力,故障恢复能力等等促使搜索引擎中偏向于使用非关系数据库。在本课题中能够选择MongoDB或BigTable等数据库系统,它们一样也有相似于Mysql强大的社区支持,开源免费等特色。

页面重访机制

由于不少网页会更新,因此需重访网页以获得最新的网页内容,来保持网页库中内容的“与时俱进”,而不一样的网站更新频率也不一样,这就要对网页变化进行分析建模。

研究代表,网页的变化能够归结为泊松过程模型,具体可见参考文献。

常见的重访策略有两种:

1)统一的重访策略:爬虫以一样的频率重访已经抓取的所有网页,以得到统一的更新机会,全部的网页不加区别地按照一样的频率被爬虫重访。

2)个体的重访策略:不一样网页的改变频率不一样,爬虫根据其更新频率来决定重访个体页面的频率。即对每个页面都量身定作一个爬虫重访频率,而且网页的变化频率与重访频率的比率对任何个体网页来讲都是相等的。

固然两种方式各有利弊,针对与本课题中电子产品的搜索,因为网页更新频率较慢,且各网页更新频率相似,因此可采用策略1.

1.3 分布式网络爬虫

前面所讲的内容大多基于单机节点之上,然而单机系统难以知足互联网上海量网页的搜索,这促使咱们选择分布式构建网页搜集系统,由于网页的搜集任务基本上可看做是相互独立的任务,使用分布式系统,能大大加快网页的搜集能力。本节将主要讲解基于分布式网络爬虫的大致架构以及设计中出现的主要问题。

在图1-1中可看到,搜集器中对应了一个控制器,在分布式搜集系统中,将会出现多个搜集器控制器对,而后再有一个总控制器,以下图所示:


图1-4分布式Web搜集系统

如图1-4即为网页搜集系统的整体分布式结构,图1-4介绍以下:

1.3.1 抓取进程

抓取进程的工做示意图以下:


图1-5 爬取进程示意流程图

注:一个爬取进程内会有多个爬取线程。

图1-5解释以下:

a.    首先爬取线程爬取URL时,先由Robots协议模块判断是否在网页服务器容许爬取的URL内,如果,则转到b,不然转到c;
b.    爬取线程将爬取到的网页递交给网页处理模块,网页处理模块会分析网页内的连接,并将网页内容组织成必定格式(3.2.1节)等,将组织后的内容压缩后插入到网页数据库中,并向爬取线程返回网页内的的全部连接内容;
c.    爬取线程将网页处理模块的全部连接(若未爬取,则为空)和当前URL递交到协调进程;
d.    协调进程向该爬取线程返回下一待爬取URL,回到a。

步骤b中,组织网页即为将多个网页组织在一块,正如1.2.1节所述,而后将组织后的内容压缩处理后插入到数据库中。

1.3.2 协调进程

协调进程的设计是关键,其中涉及到为爬取进程分配URL,处理非本区域URL,管理爬虫线程等等工做。

协调进程从0开始编号,直到n-1,其中n为爬虫主机数,各个协调进程管理本身所属的URL,即为如下策略:

URLs = {URL1,URL2, …, URLn},即URLs为全部URL的集合,定义HOST(URL)为一个网页地址的域名部分,一般对应某台Web服务器,例如:URL = http://www.scie.uestc.edu.cn/main.php?action=viewTeacher,则HOST(URL)= http://www.scie.uestc.edu.cn,所采起的策略是创建一个HOST(URL)到[n]之间的映射,一旦一个HOST(URL)映射到了某一搜集节点,该节点就要负责HOST(URL)下面全部页面的收集。映射函数可采用散列函数。每一个协调进程同时维护还要维护两张表,正如3.2.1节所述,visited_table和unvisited_table,协调进程工做的具体伪码流程以下[2]

for(;;)
begin
a.    等待从其它节点传来的一个URL,或者它所管辖的抓取进程返回一个URL及相关links。
b.    若获得其它节点传来的一个URL
b.1 看URL是否已经出如今visited_table中,若没有,则将URL放到unvisited_table中;
       c. 若获得从抓取进程返回的URL,取得超连接links;
              c.1 从unvisited_table中分给给该抓取进程一个新的URL,并将返回的URL放到visited_table中;
              c.2 并对每一个超连接符号串HOST(link)进行模n散列,获得某个整数I;
              c.3 对每个超连接link及其对应整数i:
                     c. 3.1 若是本节点编号为i,执行b.1的动做
                     c. 3.2 不然,将link发给节点i
end

上述伪代码即为协调进程工做算法,详细解释以下:

步骤a中协调进程中,只会处理属于本节点区域的URL,因此它会等待两个事件:其它节点传来属于本节点的URL和本节点上爬取进程传来的爬取的URL及相关links:

当此事件是其它节点传来URL,则首先须要验证该URL是否已经访问过(使用hash函数在visited_table中比较,正如1.2.1节所述),若未访问过,则插入到unvisited_table中供爬取进程爬取;

当此事件是本节点的爬取进程爬取的URL和相关links时(其中的相关links即为网页处理模块已分析出的网页内容中的连接),则协调进程会给该爬取进程分配下一待爬取URL。而后协调进程会分析相关links,对连接中的URL做散列操做,若散列的结果为本协调进程的编号时,则执行b.1操做,即判断该URL是否已经访问,若已访问,则丢弃,不然,则插入到unvisited_table中;当散列的结果不是本协调进程时,则发送给相应的协调进程。

1.3.3 调度模块

调度模块的工做就是维护系统内全部登记进程的信息,包括它们的IP地址和端口号,当任何一个协调进程的信息有所变化时,该模块负责将更新的信息转送给其它协调进程。

调度模块是网页搜集系统可扩展性的关键,它会为各协调进程分配URL,正如上一节中所述。系统扩展性体如今于:当其中一个协调进程模块因某种缘由而崩掉时,调度模块会将该协调进程的信息分配到其它协调进程模块。

1.4 小结

本章内容主要讲解了电子产品网页搜集系统的组成、关键问题和设计细节。最开始引出一个网络爬虫的概念,而后叙述网络爬虫须要考虑的一系列问题,例如避免URL重复、格式转换、存储等等,由于单机系统难以适应海量网页的抓取,接着文章讲解了分布式网页搜集系统的系统架构结束了本章的内容,固然,实际设计系统时,还会在这些内容上根据实际状况进行取舍。


参考文献

[1] 潘雪峰, 花贵春, 梁斌. 走进搜索引擎.2011.5. 电子工业出版社. [2]  W.BruceCroft, Donald Metzler, Trevor Strohman等. 2010.2. 搜索引擎: 信息检索实践. 北京:机械工业出版社. [3] 李晓明, 闫宏飞, 王继民等. 2012. 搜索引擎: 原理, 技术与系统. 北京:科学出版社. [4]  https://en.wikipedia.org/wiki/Web_search_engine. [5]  https://en.wikipedia.org/wiki/Hash_function. [6]  https://en.wikipedia.org/wiki/Bloom_filter. [7]  Bloom,Burton H. (1970), "Space/Time Trade-offs in Hash Coding with AllowableErrors", Communications of the ACM 13 (7):422–426, doi:10.1145/362686.362692 [8]  https://en.wikipedia.org/wiki/Naive_Bayes_classifier. [9]  https://en.wikipedia.org/wiki/Support_vector_machine. [10]  CHO, J. AND GARCIA-MOLINA, H.2000a, Estimating frequency of change. ACM Transactions on Internet Technology,Vo1.3, No.3, 2003.8. [11]  https://en.wikipedia.org/wiki/NoSQL [12]  https://en.wikipedia.org/wiki/Rabin_fingerprint 
相关文章
相关标签/搜索