作者:
江南白衣 是一个基于,类似google的完整网络搜索引擎凯发天生赢家一触即发官网的解决方案,基于的分布式处理模型保证了系统的性能,类似eclipse的插件机制保证了系统的可客户化,而且很容易集成到自己的应用之中。
nutch 0.8 完全使用hadoop重写了骨干代码,另有,非常值得升级。
1.nutch 0.8 的安装与运行
nutch 0.7.2的中文安装文档满街都是,nutch 0.8的安装文档见 , 要注意两点:
一是 crawl命令里的urls参数从指定文件变为了指定目录, 即原来的urls 要改存到urls/foo 里。
二是 nutch-default.xml里http.agent.name属性默认为空,必须在nutch-site.xml中为该属性设值,否则会出错。
注意nutch 爬行时的信息用log4j输出在/logs 目录下了,默认不再直接输出到屏幕,除非你在配置文件里设fetcher.verbose为true。
luke( 是一个必备的索引阅读工具。
另外,nutch需要在unix下奔跑,如果要装在windows上,大家可以先装个cygwin。(下载它的setup.exe 在线安装很快装完)。
最后,也不同了。
2.nutch you should know
2.1 一份文档
nutch的文档不多,而且多是安装文档,要深入nutch,就必须一字不漏的阅读:
和
然后就是看源码了,好在nutch的源码非常均匀,简短,没有花哨的技巧,很容易把事情看明白。
2.2 三个目录
首先理解nutch的三个数据目录:
1.crawdb,linkdb 是web link目录,存放url 及url的互联关系,作为爬行与重新爬行的依据,页面默认30天过期。
2.segments 是主目录,存放抓回来的网页。页面内容有bytes[]的raw content 和 parsed text的形式。nutch以广度优先的原则来爬行,因此每爬完一轮会生成一个segment目录。
3.index 是lucene的索引目录,是indexs里所有index合并后的完整索引,注意索引文件只对页面内容进行索引,没有进行存储,因此查询时要去访问segments目录才能获得页面内容。
2.3 爬行过程
爬行过程在 里已有详细说明,或许直接看crawl类来理解爬行的过程。
这里有一幅更直观的图:
nutch用入口地址,地址正则表达式,搜索深度三种形式来限制。
因为使用了hadoop(下篇再讲),nutch的代码都按照hadoop的模式来编写以获得分布式的能力,因此要先了解一下hadoop,明白它mapper,reducer, inputformat, outputformat类的作用才能更好的阅读。
1.fetcher类, 在run()里多线程运行fetcherthread,并调用恰当的protocol插件(支持http,ftp等协议)获取内容,调用恰当的parser将内容(html,pdf,excel)分析为文本,然后把内容放到fetcheroutput类里,最后由fetcheroutputformat类定义写盘到segments的过程。
2.indexer类,使用hadoop遍历所有segments 目录,将parsedata文件序列化成parsedata类,从中获得各种资料然后调用插件进行索引,最后仍然由ouputformat类完成写入索引的工作。
注意,如果你仅想使用nutch的爬虫,而不是其索引功能,可以仿照indexer重写自己的实现,比如把segments内容直接搬进数据库。
3.nutch 每条索引记录的字段
url: 作为唯一标标识值,由basicindexingfilter类产生。
segment:由indexer类产生。nutch抓回来的页面内容放在segments目录,lucene只会索引,不会store原文内容,因此在查询时要以segment与url作为外键,由fetchedsegments类根据hitsdetail从segments目录获得content。
boost:优先级,由indexer类调用插件计算产生。
title:显示标题,在basicindexingfilter插件中被索引和存储。
content: 主要的被搜索项,在basicindexingfilter插件中被索引。
2.4 搜索过程
nutch提供了一个fascade的nutchbean类供我们使用,一段典型的代码如下
nutchbean bean = new nutchbean();
query query = query.parse(args[0]);
hits hits = bean.search(query, num_hits,"title",true);
for (int i = 0; i < hits.getlength(); i) {
hit hit = hits.gethit(i);
hitdetails details = bean.getdetails(hit);
string title = details.getvalue("title");
string url = details.getvalue("url");
string summary =bean.getsummary(details, query);
}
这里nutchbean为我们做了几样事情:
一是按title field来排序。
二是支持分布式查询,如果有配置servers,就会使用hadoop的系统,调用所有server上的nutchbeans,最后规约出总的结果。
三是每个站点像google一样只显示分数最高的一页,如果用户还想看同站的其他结果,就需要进一步调用api访问。
四是生成summary,从segments目录按segments和url 获得content, 并按一定算法抽取出像google一样的包含关键字的文档片断。
3. 修改源码或编写插件
nutch的源码很容易修改和重新编译,注意新编译的class要压回nutch-0.8.job(实际是一个jar)才能生效。
nutch的插件机制及度类似eclipse, 详看,只要实现某个插件接口,然后在plugins.xml里定义class,扩展点和依赖的jar,如
="index-basic" version="1.0.0" provider-name="nutch.org">
="index-basic.jar">
="*"/>
="nutch-extensionpoints"/>
="org.apache.nutch.indexer.basic"
name="nutch basic indexing filter"
point="org.apache.nutch.indexer.indexingfilter">
="basicindexingfilter" class="org.apache.nutch.indexer.basic.basicindexingfilter"/>
最后是八卦,dedian同志翻译的。
最最后,感谢创造 "c 必知必会" 这个短语的译者:)