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智能搜索引擎都具有一定的参考和借鉴价值。利用概念词库建立智能更高的网络机器人能更好的提高查全率,这是我们今后的主要研究方向之一。