网络蜘蛛及搜索引擎基本原理(转)
摘要:高性能网络机器人是新一代Web智能搜索引擎的核心,网络机器人是否高效直接影响搜索引擎的效能的发挥。对开发高性能网络机器人所涉及的关键技术和算法进行了详细地分析。最后,给出了程序的关键类,有助于工程的实际应用和开发。
关键字:Web ;搜索引擎;网络机器人;Java
1 高性能网络机器人程序的研究意义
Web搜索引擎技术是当今网络信息处理领域的一个热点和难点。Web可以看作是一个庞大的分布式网络数据库,对于这样一个信息量飞速增长的数据库,如果人工地去检索和分类整个Web将是一项非常巨大的工程,因此在搜索引擎技术中我们必须采用网络机器人在完成这项任务,我们研究的网络机器人程序就是这么一种专业化的能高效地扫描Web站点并检索其内容的程序。
网络机器人程序是Web搜索引擎技术中关键的一部分,一般的搜索引擎由网络机器人、索引器、检索器和用户接口、Internet网络等五部分组成,简单地说,网络机器人程序的功能就是在Web上自动地搜索采集网页。但是随着用户需求的不断提高,目前基于关键字查询的搜索引擎已经不能满足用户对搜索结果要求更准、搜索范围更大的需求。因此新一代的智能搜索引擎要求网络机器人程序具有更高的性能,能够更快更新网页、更广搜索网页,所以研究高性能的网络机器人程序对搜索引擎的发展具有直接的现实意义和重要的学术价值。
2 Java套接字编程
网络是一个客户与服务器的世界,在网络上的几乎所有程序都是在处理客户进程和服务器进程之间的对话,我们所研究的网络机器人程序是浏览Internet的客户/服务器的程序。想到Interne会自然的想到Web,Web是一种建立在HTTP之上的协议,而HTTP又是建立在TCP/IP之上的协议,它同时也一种套接字协议,因此我们可以这样说,Internet的实质就是采用套接字连接TCP/IP协议的网络。
Java有非常简单的套接字编程,Java定义了两个类:Socket和ServerSccket,它们是利用Java进行网络编程的重要类。如果编写的程序是扮演服务器的角色,就应该采用ServerSocket类;如果程序是连接到服务器的那么他扮演的是客户端的角色,我们应该使用Socket类,我们研究的网络机器人程序扮演的就是客户端的角色。
3 关键技术的研究
网络机器人程序的工作是异常繁重的,好像永远都不会结束,网络机器人一边访问网页,一边又要查找下一步要访问的网页,访问了一个站点以后,仍然会有其它站点加入队列中,网络机器人程序的作业是按指数级增长的,所以对于大型的智能搜索引擎来说,提高网络机器人程序的效率是非常重要的,以下是开发高性能的网络机器人程序不可或缺的技术。
3.1 多线程技术
对于一个程序员来说,要掌握多线程的编程技术确实有些难度,但更难的是,要确定什么时候需要用到多线程技术、怎么划分线程。多线程是一个应用程序在同一时刻运行超过一个任务的能力,多线程是发生在一个应用程序内部的,它们使用同一内存空间,所以一个进程的所有线程可以很容易地共享全局数据和资源。
网络机器人程序需要下载数十个甚至成百上千的网页,如果我们采用单线程来完成这一任务,效率是十分低的,程序的瓶颈就在于网络机器人程序在向服务器发出下载网页的请求后必须等待服务器的响应,可想而知,单线程技术需要一个接一个地去等待服务器的对请求的响应,等待时间将是对每一个网页请求等待响应的时间累加。
网络机器人程序必须采用多线程技术,多线程技术允许对成百上千的网页的等待时间结合在一起,众多的线程让网络机器人程序能同时等待大量的网页,而不是让它们一个接一个的执行。
3.2 数据库技术
网络机器人程序必须跟踪它所遇到的每一个URL(Uniform Resource Locator),对这个URL列表的管理就是网络机器人程序的作业管理,作业管理对于一个高效的网络机器人程序是非常重要的,这是因为网络机器人程序必须跟踪所访问的上千个网页的数据。
网络机器人程序的作业管理通常采用两种方法:一种是基于内存的队列管理,另一种是基于SQL(Structured Query Language)数据库的队列管理。如果网络机器人程序访问大型的Web服务器时,利用基于内存来存储和管理大型站点的列表,就会显得速度很慢,消耗计算机资源越来越多,最终导致网络机器人的工作效率大大下降。所以管理和维护大型的Web站点的网页列表必须采用基于SQL的数据库队列管理机制。利用DBMS(Database Management System)管理大型的网页列表能大大缓解内存的使用,提高网络机器人程序的运行效率。
3.3 数据库访问技术
网络机器人程序采用基于SQL的数据库队列管理机制,必须有相应的数据库访问技术。Java为我们提供一组成为JDBC(Java Database Connectivity,Java数据库互连)的类来访问DBMS.JDBC的用途是允许向数据库发送SQL语句,从而让你指定希望从数据库返回的数据。在Java中,有四种类型的数据库驱动程序可以使JDBC有效的访问数据库,它们分别是JDBC-ODBC桥,部分Java和部分本机驱动程序,中间数据访问服务器以及纯Java驱动程序。
将多线程技术、数据库技术和JDBC这些技术有效的结合在一起,我们就能创建高性能的网络机器人程序。
4 设计思想与算法分析
4.1 网页的链接类型
网络机器人程序在遍历Internet时,必须从一个网页搜索到另一个网页,为了达到这个目的,网络机器人程序必须能够找到保存在它所访问的每个网页上的链接。网络机器人程序通过分析网页的HTML代码查找网页内所有链接到其它网页的标签,根据标签的属性HREF(Hypertext Reference,超文本链接)的值,网络机器人程序将会遇到三种链接类型:内部链接(Internal link)、外部链接(External link)和其它连接(other link)。内部链接指的是超链接所指向的网页与包含该链接的网页在同一台Web服务器中;外部链接指的是超链接所指向的网页所在的Web站点与包含该链接的Web站点不同;其它链接指的是超链接指向非网页的资源,如指向E-mail地址等。
4.2 程序的设计思想
开发和设计网络机器人程序有两种思想可以选择:一种就是将程序设计为递归的程序;另一种就是将程序设计为非递归的程序。采用递归设计的程序思路清晰简单,但存在两个主要的问题:第一问题就是如果程序要运行很多次,被压入递归的堆栈会变得非常大,它可能会耗尽整个堆栈的内存并终止程序的运行;第二问题就是多线程技术与递归技术不能兼容。所以开发高性能的网络机器人程序不能采用递归的程序设计思想。
我们研究的高性能网络机器人采用的是非递归程序设计思想,当使用非递归的方法时,先给定网络机器人一个要访问的网页集合,它会把这一集合加到它将要访问站点的队列中去。网络机器人发现每个新的网页时不使用调用自身的方法,而是将新发现的链接加入到该队列中。当网络机器人处理完当前的网页后,它会在队列中查找要处理的下一页。
实际工作的时候网络机器人总共使用了四个队列,每个这样的队列保存着同一处理状态的URL,它们如下:
等待队列:在这个队列中,URL等待被网络机器人处理。新发现的URL被加入到这个队列。
处理队列:当网络机器人开始处理时,它们被传送到这个队列。当一个URL被处理后,它被移送到错误队列或者完成队列中。
错误队列:如果在处理该网页时发生了错误,它的URL将被加入到错误队列中。网络机器人将不会对加入到错误队列的网页做进一步地处理。
完成队列:如果在下载网页时没有发生错误,该URL将被加入到完成队列中。加入到完成队列中的URL将不会再移入其他队列中。
URL处理状态流程图:
4.3 算法分析
我们的算法设计主要就是依据非递归的思想构造的,当一个URL被加入到等待队列中时,网络机器人就会开始运行。只要等待队列中有一个网页或网络机器人正在处理一个网页,网络机器人就会继续它的工作。当等待队列为空并且当前没有处理任何网页,网络机器人就会停止它的工作。基本的算法如下所示:
Initialize URLS;//用一个URL集合初始化网络机器人。
Queue enum{WaitQ,FinishQ,RunQ,MistakeQ};//队列类型:等待、完成、处理、错误队列。
FileText;
LinkType enum{InternalLink,ExternalLink,OtherLink};//超链类型:内部、外部、其他链接。
Begin
For url in URLS Do
PopQueue(url,WaitQ);//初始化URL集合被加入到等待队列中。
While WaitQ is not empty Do//判断等待队列是否有URL.。
Begin
url=PushQueue(WaitQ);//从等待队列中取出URL。
While RunQ is not empty Do//判断处理队列是否有URL。
Document=PopQueue(url,RunQ,LinkType);
SaveFileText(Document,FileText);//下载并保存处理队列中URL对应的网页。
If Extract(NewURLS) from Document is not Null//从下载的网页中找新的链接。
Begin
For url in NewURLS Do
Begin
If url is not in FinishQ Then//如完成队列中没有URL。
If url linktype is EnternalLink Then//如链接是外部链接。
PopQueue(url,WaitQ,LinkType);//将外部链接加入到等待队列中。
Else
PopQueue(url,RunQ,LinkType);//否则将链接加入到处理队列中。
End;
End;
End;
PopQueue(url,FinishQ,LinkType) ;
End While;
End
5 程序的实现
网络机器人程序是通过Java语言编写的,Java是面向对象的编程语言,将各个模块的主要功能封装在相对独立的类中,并通过接口函数将它们有效地连接起来,形成一个完整的系统。这种结构可以方便地引入新的方法改善和提高系统的功能,也可以建立新的类扩充其系统的功能。
下面给出实现系统的几个关键类:
Robot类―――网络机器人主要通过Robot类来实现的,这个类包含很多起接口作用的方法,
主要完成控制Robot运行,组织和管理所访问过的和将要访问的站点列表。
主要的方法有:
synchronized public void addWorkload(String url);//向作业管理器添加一个作业。
synchronized public void getWorkload(String url);//从作业管理器获得一个作业。
synchronized public Boolean foundInternalLink(String url);//发现内部链接并处理。
synchronized public Boolean foundExternalLink(String url);//发现外部链接并处理。
synchronized public Boolean foundOtherLink(String url);//发现其它链接并处理。
synchronized public void processPage(HTTP page);//用于处理网页,是网络机器人所要完成的实际工作。
synchronized public void robotComplete();//当网络机器人没有工作时调用。
public void setMaxBody(int mx);//设置要下载的正文大小。
public void getMaxBody(int mx);//返回要下载的正文大小。
public void run();//启动机器人进程。
public void halt();//停止机器人运行。
RobotSQLWorkload类―――是网络机器人的作业管理器,可以将作业存储在SQL数据库中,通过使用SQL数据库,作业管理器可以处理大型的站点,也是实现高性能网络机器人重要的类。
主要方法:
synchronized public String assignWorkload();//从等待队列中请求一个URL送入处理队列中。
synchronized public void addWorkload(String url);//将一个新的URL送入等待队列。
synchronized public void completeWorkload(String url,Boolean error);//决定送入完成队列还是错误队列。
protected void setStatus(Sting url,char status);//设置URL的状态:等待、运行、完成、错误。
synchronized public char getURLStatus(String url);//返回URL的状态类型。
synchronized public void clear();//清除作业管理器的存储。
RobotWorker类―――-高性能的网络机器人应该是多线程的,把任务分成许多小任务,必须有一种方法在不同的线程间分配任务,工作的基本单元就是RobotWorker类对象。
主要方法:
public Boolean isBusy();//返回线程的对象的状态是忙还是空闲。
public void run();//线程处于空闲则等待作业管理器分配一个作业,并通知此线程忙。
protected void processWorkload();//处理作业管理器中的作业。
public HTTP getHTTP();
6 小结
开发高性能的网络机器人对于提高Web搜索引擎的整体性能起着至关重要的作用,也是研究和开发新一代的智能搜索引擎必然要求,本文研究了开发高性能网络机器人所涉及的不可或缺的关键技术、程序设计思想与算法,并对实现程序功能的一些关键类进行了详细地分析。这些对于开发相应的自主产权的Web智能搜索引擎都具有一定的参考和借鉴价值。利用概念词库建立智能更高的网络机器人能更好的提高查全率,这是我们今后的主要研究方向之一。