冬冬阳光 2013-07-30
转载:原创地址:https://www.ibm.com/developerworks/cn/opensource/os-cn-heritrix/
本文由浅入深,详细介绍了Heritrix在Eclipse中的配置、运行。最后对其进行扩展,介绍如何实现只抓取特定网站的页面。
通过本文,读者可以了解Heritrix的相关特点以及在Eclipse中的配置运行,能够从零开始构建特定站点的专有爬虫,从而为网站增加全文检索服务。
背景
随着网站内容的增加,为其添加搜索功能是一个常见的需求,搜索引擎也已成为互联网最重要的应用之一。你是否觉得普通的数据库检索已经不能满足你的查询需求了呢?是否希望花最小的代价为你的网站建立一个像Google、百度那样的全文搜索引擎?是否希望创建自己专有的搜索引擎而不是想尽办法SEO(SearchEngineOptimization,搜索引擎优化)来等着Google、百度收录你的网站?借助于开源工具的力量,你将很容易实现上述目标。
搜索引擎的实现过程,可以看作三步:1.从互联网上抓取网页2.对网页进行处理,建立索引数据库3.进行查询。因此无论什么样的搜索引擎,都必须要有一个设计良好的爬虫来支持。Heritrix是SourceForge上基于Java的开源爬虫,它可以通过Web用户界面来启动、设置爬行参数并监控爬行,同时开发者可以随意地扩展它的各个组件,来实现自己的抓取逻辑,因其方便的可扩展性而深受广大搜索引擎爱好者的喜爱。
虽然Heritrix功能强大,但其配置复杂,而且官方只在Linux系统上测试通过,用户难以上手。本文由浅入深,详细介绍Heritrix在windows下Eclipse中的配置运行,并对其进行简单扩展,使其只针对某一特定网站进行抓取,为构建相应站点的全文搜索引擎打好基础。
---------------------------------------------------------------------------------
Heritrix下载
目前Heritrix的最新版本是1.14.4(2010-5-10发布),您可以从SourceForge(http://sourceforge.net/projects/archive-crawler/files/)上下载。每个版本都有四个压缩包,两个.tar.gz包用于Linux下,.zip用于windows下。其中heritrix-1.14.4.zip是源代码经过编译打包后的文件,而heritrix-1.14.4-src.zip中包含原始的源代码,方便进行二次开发。本文需要用到heritrix-1.14.4-src.zip,将其下载并解压至heritrix-1.14.4-src文件夹。
----------------------------------------------------------------------------------
在Eclipse中的配置
首先在Eclipse中新建Java工程MyHeritrix。然后利用下载的源代码包根据以下步骤来配置这个工程。
1.导入类库
Heritrix所用到的工具类库都在heritrix-1.14.4-src\lib目录下,需要将其导入MyHeritrix工程。
1)将heritrix-1.14.4-src下的lib文件夹拷贝到MyHeritrix项目根目录;
2)在MyHeritrix工程上右键单击选择“BuildPathConfigureBuildPath…”,然后选择Library选项卡,单击“AddJARs…”,如图1所示。
3)在弹出的“JARSelection”对话框中选择MyHeritrix工程lib文件夹下所有的jar文件,然后点击OK按钮。如图2所示。
设置完成后如图3所示:
2.拷贝源代码
1)将heritrix-1.14.4-src\src\java下的com、org和st三个文件夹拷贝进MyHeritrix工程的src下。这三个文件夹包含了运行Heritrix所必须的核心源代码;
2)将heritrix-1.14.4-src\src\resources\org\archive\util下的文件tlds-alpha-by-domain.txt拷贝到MyHeritrix\src\org\archive\util中。该文件是一个顶级域名列表,在Heritrix启动时会被读取;
3)将heritrix-1.14.4-src\src下conf文件夹拷贝至Heritrix工程根目录。它包含了Heritrix运行所需的配置文件;
4)将heritrix-1.14.4-src\src中的webapps文件夹拷贝至Heritrix工程根目录。该文件夹是用来提供servlet引擎的,包含了Heritrix的webUI文件。需要注意的是它不包含帮助文档,如果想使用帮助,可以将heritrix-1.14.4.zip\docs中的articles文件夹拷贝到MyHeritrix\webapps\admin\docs(需新建docs文件夹)下。或直接用heritrix-1.14.4.zip的webapps文件夹替换heritrix-1.14.4-src\src中的webapps文件夹,缺点是这个是打包好的.war文件,无法修改源代码。
拷贝完毕后的MyHeritrix工程目录层次如图4所示。这里运行Heritrix所需的源代码等已经准备完备,下面需要修改配置文件并添加运行参数。
3.修改配置文件
conf文件夹是用来提供配置文件的,里面包含了一个很重要的文件:heritrix.properties。heritrix.properties中配置了大量与Heritrix运行息息相关的参数,这些参数的配置决定了Heritrix运行时的一些默认工具类、WebUI的启动参数,以及Heritrix的日志格式等。当第一次运行Heritrix时,只需要修改该文件,为其加入WebUI的用户名和密码。如图5所示,设置heritrix.cmdline.admin=admin:admin,“admin:admin”分别为用户名和密码。然后设置版本参数为1.14.4。
4.配置运行文件
在MyHeritrix工程上右键单击选择“RunAsRunConfigurations”,确保Main选项卡中的Project和Mainclass选项内容正确,如图6所示。其中的Name参数可以设置为任何方便识别的名字。
然后在Classpath页选择UserEntries选项,此时右边的Advanced按钮处于激活状态,点击它,在弹出的对话框中选择“AddFolders”,然后选择MyHeritrix工程下的conf文件夹。如图7所示。
至此我们的MyHeritrix工程已经可以运行起来了。下面我们来看看如何启动Heritrix并设置一个具体的抓取任务。
----------------------------------------------------------------------------------
创建网页抓取任务
找到org.archive.crawler包中的Heritrix.java文件,它是Heritrix爬虫启动的入口,右键单击选择“RunAsJavaApplication”,如果配置正确,会在控制台输出如图8所示的启动信息。
在浏览器中输入http://localhost:8080,会打开如图9所示的WebUI登录界面。
输入之前设置的用户名/密码:admin/admin,进入到Heritrix的管理界面,如图10所示。因为我们还没有创建抓取任务,所以Jobs显示为0。
Heritrix使用Web用户界面来启动、设置爬行参数并监控爬行,简单直观,易于管理。下面我们以北京林业大学首页(http://www.bjfu.edu.cn/)为种子站点来创建一个抓取实例。
在Jobs页面创建一个新的抓取任务,如图11所示,可以创建四种任务类型。
Basedonexistingjob:以一个已经有的抓取任务为模板生成新的抓取任务。
Basedonarecovery:在以前的某个任务中,可能设置过一些状态点,新的任务将从这个设置的状态点开始。
Basedonaprofile:专门为不同的任务设置了一些模板,新建的任务将按照模板来生成。
Withdefaults:这个最简单,表示按默认的配置来生成一个任务。
这里我们选择“Withdefaults”,然后输入任务相关信息,如图12所示。
注意图11中下方的按钮,通过这些按钮可以对抓取工作进行详细的设置,这里我们只做一些必须的设置。
首先点击“Modules”按钮,在相应的页面为此次任务设置各个处理模块,一共有七项可配置的内容,这里我们只设置CrawlScope和Writers两项,下面简要介绍各项的意义。
1)SelectCrawlScope:CrawlScope用于配置当前应该在什么范围内抓取网页链接。例如选择BroadScope则表示当前的抓取范围不受限制,选择HostScope则表示抓取的范围在当前的Host范围内。在这里我们选择org.archive.crawler.scope.BroadScope,并单击右边的Change按钮保存设置状态。
2)SelectURIFrontier:Frontier是一个URL的处理器,它决定下一个被处理的URL是什么。同时,它还会将经由处理器链解析出来的URL加入到等待处理的队列中去。这里我们使用默认值。
3)SelectPreProcessors:这个队列的处理器是用来对抓取时的一些先决条件进行判断。比如判断robot.txt信息等,它是整个处理器链的入口。这里我们使用默认值。
4)SelectFetchers:这个参数用于解析网络传输协议,比如解析DNS、HTTP或FTP等。这里我们使用默认值。
5)SelectExtractors:主要是用于解析当前服务器返回的内容,取出页面中的URL,等待下次继续抓取。这里我们使用默认值。
6)SelectWriters:它主要用于设定将所抓取到的信息以何种形式写入磁盘。一种是采用压缩的方式(Arc),还有一种是镜像方式(Mirror)。这里我们选择简单直观的镜像方式:org.archive.crawler.writer.MirrorWriterProcessor。
7)SelectPostProcessors:这个参数主要用于抓取解析过程结束后的扫尾工作,比如将Extrator解析出来的URL有条件地加入到待处理的队列中去。这里我们使用默认值。
设置完毕后的效果如图13:
设置完“Modules”后,点击“Settings”按钮,这里只需要设置user-agent和from,其中:
“@VERSION@”字符串需要被替换成Heritrix的版本信息。
“PROJECT_URL_HERE”可以被替换成任何一个完整的URL地址。
“from”属性中不需要设置真实的E-mail地址,只要是格式正确的邮件地址就可以了。
对于各项参数的解释,可以点击参数前的问号查看。本次任务设置如图14所示。
完成上述设置后点击“Submitjob”链接,然后回到console控制台,可以看到我们刚刚创建的任务处于pending状态,如图15所示。
点击“Start”启动任务,刷新一下即可看到抓取进度以及相关参数。同时可以暂停或终止抓取过程,如图16所示。需要注意的是,进度条的百分比数量并不是准确的,这个百分比是实际上已经处理的链接数和总共分析出的链接数的比值。随着抓取工作不断进行,这个百分比的数字也在不断变化。
同时,在MyHeritrix工程目录下自动生成“jobs”文件夹,包含本次抓取任务。抓取下来网页以镜像方式存放,也就是将URL地址按“/”进行切分,进而按切分出来的层次存储。如图17所示。
从图17也可以看出,因为我们选择了BroadScope的抓取范围,爬虫会抓取所有遇到的URL,这样会造成URL队列无限制膨胀,无法终止,只能强行终止任务。尽管Heritrix也提供了一些抓取范围控制的类,但是根据实际测试经验,如果想要完全实现自己的抓取逻辑,仅仅靠Heritrix提供的抓取控制是不够的,只能修改扩展源代码。
下面本文以实现抓取北京林业大学(www.bjfu.edu.cn)下相关页面为例说明如何扩展Heritrix实现自己的抓取逻辑。
---------------------------------------------------------------------------------
扩展Heritrix
我们先来分析一下Heritrix的总体结构和URI的处理链。
Heritrix的总体结构
Heritrix采用了模块化的设计,用户可以在运行时选择要用的模块。它由核心类(coreclasses)和插件模块(pluggablemodules)构成。核心类可以配置,但不能被覆盖,插件模块可以由第三方模块取代。所以我们就可以用实现了特定抓取逻辑的第三方模块来取代默认的插件模块,从而满足自己的抓取需要。
Heritrix的整体结构如图18所示。其中CrawlController(下载控制器)整个下载过程的总控制者,整个抓取工作的起点,决定整个抓取任务的开始和结束。每个URI都有一个独立的线程,它从边界控制器(Frontier)获取新的URI,然后传递给Processorchains(处理链)经过一系列Processor(处理器)处理。
URI处理流程
处理链由多个处理器组成,共同完成对URI的处理,如图19所示。
1)Pre-fetchprocessingchain(预处理链),用来判断抓取时的一些先决条件,如robot协议、DNS等。
2)Fetchprocessingchain(抓取处理链),解析网络传输协议,从远程服务器获取数据。
3)Extractorprocessingchain(抽取处理链),从网页中抽取新的URL。
4)Write/indexprocessingchain(写处理链),负责把数据写入本地磁盘。
5)Post-processingchain(后置处理链),在整个抓取解析过程结束后,进行一些扫尾工作,比如将前面Extractor解析出来的URL有条件的加入到待处理队列中去。这里我们只需要控制加入到待处理队列中的URL,就可以控制抓取的范围。
扩展FrontierScheduler来抓取特定网站内容
FrontierScheduler是org.archive.crawler.postprocessor包中的一个类,它的作用是将在Extractor中所分析得出的链接加入到Frontier中,以待继续处理。在该类的innerProcess(CrawlURI)函数中,首先检查当前链接队列中是否有一些属于高优先级的链接。如果有,则立刻转走进行处理;如果没有,则对所有的链接进行遍历,然后调用Frontier中的schedule()方法加入队列进行处理。其代码如图20所示。
从上面的代码可以看出innerProcess()函数并未直接调用Frontier的schedule()方法,而是调用自己内部的schedule()方法,进而在这个方法中再调用Frontier的schedule()方法。而FrontierScheduler的schedule()方法实际上直接将当前的候选链接不加任何判断地直接加入到抓取队列当中了。这种方式为FrontierScheduler的扩展留出了很好的接口。
这里我们需要构造一个FrontierScheduler的派生类FrontierSchedulerForBjfu,这个类重载了schedule(CandidateURIcaUri)这个方法,限制抓取的URI必须包含“bjfu”,以保证抓取的链接都是北林内部的地址。派生类FrontierSchedulerForBjfu具体代码如图21所示。
然后,在modules文件夹中的Processor.options中添加一行“org.archive.crawler.postprocessor.FrontierSchedulerForBjfu|FrontierSchedulerForBjfu”,这样在爬虫的WebUI中就可以选择我们扩展的org.archive.crawler.postprocessor.FrontierSchedulerForBjfu选项。如图22所示。
最终抓取的页面如图23所示,全部都是http://www.bjfu.edu.cn下的页面。是不是很简单呢?当然,如果只是想实现这个抓取目标,不用修改源代码,通过在WebUI中设置抓取规则也可以满足要求。本文只是以此为例说明Heritrix如何扩展Heritrix。
---------------------------------------------------------------------------------
常见问题
1.Accessrestriction错误
错误信息:
Accessrestriction:ThetypeFileURLConnectionisnotaccessibleduetorestrictiononrequiredlibraryC:\ProgramFiles\Java\jdk1.6.0_20\jre\lib\rt.jar,如图24所示。
解决方案:
这是JRE的访问限制导致报错,在MyHeritrix工程上右键单击选择“BuildPathConfigureBuildPath…”,然后选择Library选项卡,将“JRESystemLibrary”删除然后重新导入一下即可修复。或者选择“WindowsPreferencesJavaCompilerErrors/Warnings”找到“DeprecatedandrestrictedAPI”下的“Forbiddenreference(accessrules)”,将默认设置“Error”改为“Warning”或“Ignore”。
2.NullPointerException的错误
错误信息如图25所示:
解决方案:
这个错误的原因是缺少了“tlds-alpha-by-domain.txt”文件,在heritrix-1.14.4-src\src\resources\org\archive\util下可以找到该文件,将其拷贝到MyHeritrix\src\org\archive\util中即可。
3.Modules界面无法改变选择项
错误信息如图26所示。
解决方案:
这是因为没有添加运行时所需的配置文件,参照本文“4.配置运行方式”为Classpath添加参数即可。