简明现代魔法 -> web设计理念 -> 论文:搜索引擎爬虫的实现

论文:搜索引擎爬虫的实现

2011-03-06

万维网是一个通过HTML格式使数十亿的文件产生联系的集合 ,然后如此规模庞大的数据已经成为信息检索的障碍,用户为了查找自己想要的资料可能要翻转数页。网络爬虫是搜索引擎的核心部分,网页爬虫持续不断的在互联网上爬行来寻找任何新的增加到网络中的页面和已经从网上删除页面。由于网页的持续的增长和动态性,遍历网络中所有的网址并处理已成为一种挑战。一个集中性的爬虫就是一个爬取特定话题,访问并收集相关网页的代理。这篇论文中会讲到我做过的一些网络爬虫的设计来检索版权侵权的工作。我们将用一个种子URL作为输入并搜索一个关键字,根据这个关键字进行检索,并且获取发现该关键字的网页。焦点在于查找包含用户检索的关键字的网页的爬行方式,我们使用广度优先的方式进行检索。现在,当我们检索的网页时,会用到文本上的模式识别。我们选择一个文件作为输入并用模式识别算法进行检索。这里,匹配只针对文本并检查网页上有多少文本可用。我用的匹配查找的算法有Knutt-Morri-Pratt, Boyer-Moore,有限自动机。

关键字:搜索引擎,聚焦爬虫,模式识别,版权侵犯

简介

万维网提供了一个很庞大的信息来源,几乎所有类型。然而,这些通常分部在许多Web服务器和主机上,并且使用了很多不同的格式。我们都希望,我们应该用更少的时间检索到最想要的结果。在本文中,我们介绍了聚焦网络爬虫的工作,通过合并找到版权侵权的过程,对于任何网络爬虫都要考虑到两点,首先,爬虫需要有计划能力,比如可以决定下一次拉取哪个页面;其次,它需要有一个高度优化和强大的系统架构,以达到每秒可以拉取大量的页面,并且防止系统崩溃,有效的管理拉拉取的页面,合适的资源和Web服务器。最近的一些学术话题很多关注第一个问题的,包括决定哪些重要的网页应首先抓取。与此相反,关注第二个问题的越来越少了。显然,所有的大搜索引擎都有高度优化的检索系统,虽然该系统的细节文档通常在他们的所有者那里,一般是保密的。目前已知的有详细文献记载的系统是在DECCompaq的Heydon和Najork开发的Mercator系统,该系统被Alta Vista采用。建立一个短时间拉取很少的网页的运行缓慢的爬虫很简单。但是,构造一个高性能系统在系统设计、I/O和网络性能、健壮性和可操纵性方面是一个很大的挑战。

每一个搜索引擎都分为很多不同的模块,这些模块中的爬虫模块是搜索引擎中最重要的,因为它有助于为搜索引擎提供最好的可能结果。爬虫是搜索引擎中'浏览'网页的一个小程序,类似与用户通过点击来访问不同的页面,程序给了一些从网上检索的用于启动的种子URL。爬虫提取检索到的网页中的URL,并将这些信息提供给爬虫控制模块。该模块对之后访问哪些页面做判定,再把这些页面链接提供给爬虫。爬虫还会拉取检索到的页面并添加到页面库。这样持续不断的爬行网页,直到本地资源耗尽,比如存储设备。

本文的其余部分的结构如下。下一节调查爬虫相关工作,第3节介绍我们使用的聚焦爬虫的原理,第4节介绍模式识别算法,第5节介绍爬虫的实现,第6节总结并对未来需要做的工作进行说明。

相关工作

网络爬虫,也被称为机器人,蜘蛛,蠕虫,网页追逐者,和流浪者,几乎和网络本身一样古老。第一个网络爬虫的开发者是Matthew Gray's Wandered,写在1993年的春天,大约正好是NCSA Mosaic浏览器的第一个版本发布的时间。

在本论文中,我们集中关注聚焦爬虫,它会根据我们给定的关键字索引相关页面。爬虫在指定的页面查找我们输入的特定关键词,首先会在种子网址中查找,然后再转向该网址的页面和该页面中其他的包含我们指定的关键字的链接中查找,一直这样爬行页面直到我们达到了我们设置的极限,但它可能找不到我们之前设置的页面数量,表明该页面没有其他的链接包含这个特定关键字。爬虫提取页面的时候也应该确保只拉取特定的链接,以保证不会总是一遍又一遍的访问同一个页面。 我们拉取完这些链接之后,会以一个txt文本作为输入并运行KMP(Knutt-Morris-Pratt),BMM(Boyer-Moore) 和有限自动机 这三种模式识别算法。

聚焦爬虫的原理

爬虫的运行的过程如上图所示,DNS 进程负责移除种子URL中的一个URL并试图通过IP协议连接该URL主机。首先,DNS进程查看DNS数据库,检查该主机是否已经被解析,如果已经解析了,则直接获取该IP,如果没有解析,DNS进程通过DNS服务器获得主机IP;之后read进程负责获取解析的IP地址,并试图打开一个HTTP socket连接来请求页面。

下载页面之后,爬虫会检查页面内容防止重复拉取,然后,提取并标准化拉取的页面中所包含的URl,核实网络机器人是否可以爬取这些页面,检查爬虫之前是否拉取过这些URL显然我们不能让服务器一直处于忙状态来检查这些信息,所以我们必须设置一些时间戳,等检查信息的时间戳耗尽了即使还没有检查完爬虫也会继续爬取页面,如果时间戳用完了还没有找到可用链接会提示找不到字符串,如果找到了爬虫会去拉取页面并在某些表里面记录下来存储在文件里面,这里,我们只拉取html页面。

模式识别

这里的模式识别的对象只针对文本,模式识别用来做句法分析。当我们去比较模式识别和普通的表达式匹配时会发现模式匹配更加强大,但是识别的过程中会慢一点。一个模式匹配就是一个字符串,所有的关键字都可以被写成大写或者小写,一个模式匹配表达式由一元的和二元的操作符组成, 空格和制表符可以用于分隔关键词,文本在发现知识的过程中有重要作用,可以用于从未结构化的或者半结构化的数据中提取隐藏的信息,这部分是之后工作的基础,由于大多网页中内嵌HTML代码,这些网页信息都是半结构化的,还有很多网页都是被链接的,也有很多冗余页面,网页文本帮助我们获取并综合有用的数据,信息和知识。

这篇论文中,模式识别这样应用在爬虫程序中,当我们启动爬虫程序,它会提供给我和关键字相关的链接,之后会读取这些链接的页面,并且只读取这些页面的内容。这里的内容是指仅仅是网页中可以获取的文本信息,不包含图片,标签,还有按钮。拉取的内容会被存储在一些文件中,但是不会包含任何的HTML标签。

我们提取文本的算法:

  • KNUTT-MORRIS-PRATT (KMP)
  • 有限自动机
  • BOYER MOORE (BMM)

KNUTT-MORRIS-PRATT 算法伪码

Knutt-Morris-Pratt algorithm的工作原理很像有限自动机算法,匹配字符串和文本从左到右进行比较,如果匹配成功,该算法会查找开始匹配位置到目前匹配位置最大的下标,从而决定匹配的位置可以向右最多移动多远,并且避免丢失可能的匹配。

我们下一步需要移动的位置的数据存储在一个辅助的"next"表里面,这个表是通过自己对自己匹配的预处理得到的,这里面包含了字符串在匹配失败时下一次要匹配的位置信息,这个"next"表是一个高级的助手。

这是一段我们对计算"next"表的简短描述:我们用一个游标去查找字符串P中最大的前缀,下标为P[1…j],通过这个字符串自己可以计算出每个位置可能移动的距离,当字符匹配时,P和next的指针都会递增,当一个匹配发生了不止一次,我们会把next[j]置为j-1,如果这个匹配已经在起始位置匹配过则next[j]置为0,i递增,通过匹配自己来检查下一次移动的位置。

输入:包含m字符的字符串 P(匹配文件)和目标网页文件

输出:匹配的数量和算法在查找匹配过程中所耗费的时间

算法主要的实现大约像下面这样:

while(I<n){
     if(pattern.charAt(j)==text.charAt(i)){
         if(j==m-1)
              return I-m+1; //match
         j++;
     }
     else if(j>0){
         j=fail[j-1];
     }
     else{
         i++;
     }
     return –1; // no match
}

只要我们没有到达文本的最末端,匹配字符串和文本就会不断的进行比较,当匹配字符串和文本匹配时,i和j都自加,当全部匹配的时候,算法会返回有效的偏移位置,对于没有匹配的情形,有一点不同:如果匹配发生在初始位置,匹配的字符串向右移动一位继续匹配,如果不是初始位置,则程序会调用辅助函数来决定下一次要移动的位置,如果到文本的末尾也没有找到匹配的字符串,程序会返回-1。

有限自动机算法伪码

这种方法使用有限自动机来扫描进行文本的模式匹配,一个有限自动机是一个五元组(S,s0,A,Σ,δ),其中:

  • S是状态的有限集合
  • S0为初始状态
  • A⊆S是一个接受状态集合
  • Σ*是有限的输入字母表
  • δ是一个从S×Σ*到S的函数,被称为自动机的转移函数。

为了使用有限自动机解决字符串匹配问题,必须根据模式P建立有限自动机,建立的状态机会有m+1种状态,并且最后一个状态是唯一的一个接收状态,我们用状态转移的步骤构建自动机"骨架",他们会在匹配的情况下被执行,然后对于不匹配的情况我们添加有向边, 为了计算转移函数,我们利用这个公式,它确定了"错误开始"的最长后缀,这也是模式P的前缀, (I,a)= max{k<=I⏐P[1…k] is suffix of P[1…I]a} , (I,a)=0表示未找到后缀。

BOYER-MOORE ALGORITHM算法伪码

在BOYER-MOORE]算法中,模式是从右至左扫描的文本的,该算法用两种不同的预处理策略,以确定尽可能小的移动,每次匹配失败时,两种算法进行计算,然后选择最大可能移动,从而对于每个个别情况都会运用最有效的策略。

第一个策略是"坏字符"启发式。这一策略集中在"坏字符"上面,这将导致不匹配。如果它根本就不包含所有在P中,该模式可移过它,如果它是在模式的某处,然后搜索最右边的"坏字符"并匹配的文本。

"坏字符"启发式的辅助函数:

public static int[] buildLastFunction(String pattern){
     int[] last = new int[128]; // assume ASCII character set
     for(int i=0;i<128;i++){
         last[i]= -1; //initialize array
     }

     for(int i=0;i<pattrn.length;i++){
         last[pattern.charAt]=i; // implicit cast to integer
         ASCII code
     }
     return last;
}

每个字母字符,我们确定模式在其最右边发生并将结果写出到一个数组里。然后,每次匹配失败时,我们查找"最后"成为坏字符的位置的值,找出模式可以向右移多远。

只使用"坏字符"启发式的简单算法:

int[] last=buildLastFunction(pattern);
int n=text.length();
int m=pattern.length();
int i=m-1;
if(i>n-1)
return –; // no match if pattern is longer than text
int j = m-1;
do{
     if(pattern.charAt(j)==text.charAt(i))
         if(j==0){
              return; // match
         } else{ // left-to –right scan
              i--;
              j--;
         }
}

else
     i=i+m-Math.min(j,1+last[text.charAt(i)]);
     j=m-1;
}

while(i<=n-1)
return –; // no match
}

首先检查模式的长度是否比文本长,设置模式和文本的指针指向起始位置,即模式最右面的字符然后进行比较,当j等于m-1时,说明发现了全部匹配,然后我们返回有效偏移的位置,如果不等,j和i递减,继续进行比较。

万一模式字符串和文本不匹配,辅助函数会被调用我们确定了在模式的最右边发生的坏字符并相应的修改J和i,如果我们有检查所有有效的移动并且已经发现不匹配,我们知道模式没有出现在文本中会返回- 1。第二个策略是"好后缀"启发式。我们尝试找到"错误起点"的最大后缀,也是模式的前缀。

总结和未来需要做的工作

爬虫是一个下载和存储网页的程序,一般是为网络搜索引擎提供数据,快速增长的互联网为寻找最合适链接带来的较大挑战。聚焦爬虫只从互联网上提取与感兴趣的主题相关的网页。截至目前,Allan Heydon 和 Marc Najork在"Mercator:可扩展的网络爬虫"对其进行描述,Mercators的主要支持可扩展定制的蚂蚁,还介绍了Mercator中用到的特别的组件。在本文中,我们使用了Mercator中在爬虫方面定义的一些组件的功能,所设计的网络爬虫程序的能够处理输入文本文件与网络连接的比较功能,该爬虫用模式识别的算法计算并获得输入文本在连接中出现的次数。

这个爬虫用了三种算法分别对文本进行模式识别并输出每一种算法计算的结果,透过这样的信息我们可以看到模式匹配算法的影响,这个爬虫只用到了一种文本查找方法,这里是模式识别,网络爬虫还可以用到其他的文字处理技术,因此可以开发一个更加智能更好用的网络爬虫来查找版权侵犯。

随机文章推荐
网站分类


注:如需转载本文,请注明出处(原文链接),谢谢。更多精彩内容,请进入简明现代魔法首页。

进入新博客
喜欢本文,就分享它吧
给我留言
您的名字:
您的邮件:
您的网站:


 

copyright © 2009 简明现代魔法    学习、分享、进步

power by Gonn 感谢所有关心和支持本站的朋友们