系统程序设计说明书.docx

上传人:b****3 文档编号:2290643 上传时间:2022-10-28 格式:DOCX 页数:26 大小:79.49KB
下载 相关 举报
系统程序设计说明书.docx_第1页
第1页 / 共26页
系统程序设计说明书.docx_第2页
第2页 / 共26页
系统程序设计说明书.docx_第3页
第3页 / 共26页
系统程序设计说明书.docx_第4页
第4页 / 共26页
系统程序设计说明书.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

系统程序设计说明书.docx

《系统程序设计说明书.docx》由会员分享,可在线阅读,更多相关《系统程序设计说明书.docx(26页珍藏版)》请在冰豆网上搜索。

系统程序设计说明书.docx

系统程序设计说明书

系统程序设计说明书

景德镇陶瓷学院

1Heritrix的架构

1.1抓取任务CrawlOrder

CrawlOrder是整个抓取工作的起点。

在上一节中已经说过,一次抓取任务包括许多的属性,建立一个任务的方式有很多种,最简单的一种就是根据默认的order.xml来配置。

在内存中,order使用CrawlOrder这个类来进行表示。

看一下API文档中CrawlOrder的继承关系图。

CrawlOrder继承自一系列的与属性设置相关的基类,它的最顶层基类是javax.management.Attribute,这是一个JMX中的类,它可以动态的反映出Java容器内某个MBean的属性变化。

CrawlOrder中的属性,是需要被随时读取和监测的。

在org.archive.crawler.settings包下有一个XMLSettingsHandler类,它可以用来帮助读取order.xml。

publicXMLSettingsHandler(FileorderFile)throwsInvalidAttributeValueException

在XMLSettingsHandler的构造函数中,其所传入的参数orderFile正是一个经过对象封装的order.xml的File。

这样,就可以直接调用其构造函数,来创建一个XMLSettingsHandler的实例,以此做为一个读取order.xml的工具。

当一个XMLSettingsHandler的实例被创建后,可以通过getOrder()方法来获取CrawlOrder的实例,这样也就可以进行下一步的工作了。

1.2中央控制器CrawlController

中央控制器是一次抓取任务中的核心组件。

它将决定整个抓取任务的开始和结束。

CrawlController位于org.archive.crawler.framework中,在它的Field声明中,看到如下代码片段。

代码1

//keysubcomponentswhichdefineandimplementacrawlinprogress

privatetransientCrawlOrderorder;

privatetransientCrawlScopescope;

privatetransientProcessorChainListprocessorChains;

privatetransientFrontierfrontier;

privatetransientToePooltoePool;

privatetransientServerCacheserverCache;

//Thisgetspassedintotheinitializemethod.

privatetransientSettingsHandlersettingsHandler;

可以看到,在CrawlController类中,定义了以下几个组件:

CrawlOrder:

这就不用说了,因为一个抓取工作必须要有一个Order对象,它保存了对该次抓取任务中,order.xml的属性配置。

CrawlScope:

这是决定当前的抓取范围的一个组件。

ProcessorChainList:

从名称上很明显就能看出,它表示了处理器链。

Frontier:

很明显,一次抓取任务需要设定一个Frontier,以此来不断为其每个线程提供URI。

ToePool:

这是一个线程池,它管理了所有该抓取任务所创建的子线程。

ServerCache:

这是一个缓存,它保存了所有在当前任务中,抓取过的Host名称和Server名称。

以上组件应该是一次正常的抓取过程中所必需的几项,它们各自的任务很独立,分工明确,但在后台中,它们之间却有着千丝万缕的联系,彼此互相做为构造函数或初始化的参数传入。

那么,究竟该如何获得CrawlController的实例,并且通过自主的编程来使用Heritrix提供的API进行一次抓任务呢?

事实上CrawlController有一个不带参数的构造函数,开发者可以直接通过它的构造函数来构造一个CrawlController的实例。

但是值得注意的一点,在构造一个实例并进行抓取任务时,有几个步骤需要完成:

(1)首先构造一个XMLSettingsHandler对象,将order.xml内的属性信息装入。

(2)调用CrawlController的构造函数,构造一个CrawlController的实例。

(3)调用CrawlController的intialize(SettingsHandler)方法,初始化CrawlController实例。

其中,传入的参数是在第一步是构造的XMLSettingsHandler实例。

(4)当上述3步完成后,CrawlController就已经具备运行的条件,可以开始运行了。

此时,只需调用它的requestCrawlStart()方法,就可以启运线程池和Frontier,然后就可以开始不断的抓取网页了。

使用CrawlController启动抓取任务

在CrawlController的initialize()方法中,Heritrix主要做了以下几件事:

(1)从XMLSettingsHandler中取出Order。

(2)检查了用户设定的UserAgent等信息,看是否符合格式。

(3)设定了开始抓取后保存文件信息的目录结构。

(4)初始化了日志信息的记录工具。

(5)初始化了使用BerkleyDB的一些工具。

(6)初始化了Scope、Frontier以及ProcessorChain。

(7)最后实例化了线程池。

在正常情况下,以上顺序不能够被随意变动,因为后一项功能的初始化很有可能需要前几项功能初始化的结果。

例如线程池的初始化,必须要在先有了Frontier的实例的基础上来进行。

读者可能对其中的BerkeleyDB感到费解,在后面的小节将详细说明。

最终启动抓取工作的是requestCrawlStart()方法。

其代码如下。

代码2

publicvoidrequestCrawlStart(){

//初始化处理器链

runProcessorInitialTasks();

//设置一下抓取状态的改变,以便能够激发一些Listeners

//来处理相应的事件

sendCrawlStateChangeEvent(STARTED,CrawlJob.STATUS_PENDING);

StringjobState;

state=RUNNING;

jobState=CrawlJob.STATUS_RUNNING;

sendCrawlStateChangeEvent(this.state,jobState);

//Aproperexitwillchangethisvalue.

this.sExit=CrawlJob.STATUS_FINISHED_ABNORMAL;

//开始日志线程

ThreadstatLogger=newThread(statistics);

statLogger.setName("StatLogger");

statLogger.start();

//启运Frontier,抓取工作开始

frontier.start();

}

可以看到,启动抓取工作的核心就是要启动Frontier(通过调用其start()方法),以便能够开始向线程池中的工作线程提供URI,供它们抓取。

下面的代码就是BdbFrontier的父类AbstractFrontier中的start()方法和unpause()方法:

代码3

publicvoidstart(){

if(((Boolean)getUncheckedAttribute(null,ATTR_PAUSE_AT_START))

.booleanValue()){

//若配置文件中不允许该次抓取开始

//则停止

controller.requestCrawlPause();

}else{

//若允许开始,则开始

unpause();

}

}

synchronizedpublicvoidunpause(){

//去除当前阻塞变量

shouldPause=false;

//唤醒所有阻塞线程,开始抓取任务

notifyAll();

}

在start()方法中,首先判断配置中的属性是否允许当前线程开始。

若不允许,则令controller停止抓取。

若允许开始,则简单的调用unpause()方法。

unpause()方法更为简单,它首先将阻塞线程的信号量设为false,即允许线程开始活动,然后通过notifyAll()方法,唤醒线程池中所有被阻塞的线程,开始抓取。

Frontier链接制造工厂

Frontier在英文中的意思是“前线,领域”,在Heritrix中,它表示一种为线程提供链接的工具。

它通过一些特定的算法来决定哪个链接将接下来被送入处理器链中,同时,它本身也负责一定的日志和状态报告功能。

事实上,要写出一个合格并且真正能够使用的Frontier绝非一件简单的事情,尽管有了Frontier接口,其中的方法约束了Frontier的行为,也给编码带来了一定的指示。

但是其中还存在着很多问题,需要很好的设计和处理才可以解决。

在Heritrix的官方文档上,有一个Frontier的例子,在此拿出来进行一下讲解,以此来向读者说明一个最简单的Frontier都能够做什么事。

以下就是这个Frontier的代码。

代码4

publicclassMyFrontierextendsModuleTypeimplementsFrontier,

FetchStatusCodes{

//列表中保存了还未被抓取的链接

ListpendingURIs=newArrayList();

//这个列表中保存了一系列的链接,它们的优先级

//要高于pendingURIs那个List中的任何一个链接

//表中的链接表示一些需要被满足的先决条件

Listprerequisites=newArrayList();

//一个HashMap,用于存储那些已经抓取过的链接

MapalreadyIncluded=newHashMap();

//CrawlController对象

CrawlControllercontroller;

//用于标识是否一个链接正在被处理

booleanuriInProcess=false;

//成功下载的数量

longsuccessCount=0;

//失败的数量

longfailedCount=0;

//抛弃掉链接的数量

longdisregardedCount=0;

//总共下载的字节数

longtotalProcessedBytes=0;

//构造函数

publicMyFrontier(Stringname){

super(Frontier.ATTR_NAME,"Asimplefrontier.");

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1