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;