初识 Nutch

初识 Nutch

本文介绍了开源搜索引擎Nutch的基本信息,并详细说明了在Eclispe下运行Nutch的步骤和需要注意的问题,并运行了一个实例对http://www.ibm.com/地址下的网页进行抓取。

宋伟 无需填写 无需填写(songwwei@cn.ibm.com), 软件工程师, EMC

2008 年 11 月 20 日

  • +内容

基本信息

Nutch是一个开放源代码(open-source)的Java搜索引擎包,它提供了构建一个搜索引擎所需要的全部工具和功能。使用Nutch不仅可以建立自己内部网的搜索引擎,同时也可以针对整个网络建立搜索引擎。除了基本的功能之外,Nutch也还有不少自己的特色,如Map-Reduce、Hadoop、Plugin等。

Nutch的总体结构

Nutch从总体上看来,分为三个主要的部分:爬行、索引和搜索,各部分之间的关系如图1所示。Web db是Nutch初始运行的URL集合;Fetcher是用来抓取网页的爬行器,也就是平时常说的Crawler;indexer是用来建立索引的部分,它将会生成的索引文件并存放在系统之中;searcher是查询器,用来完成对某一词条的搜索并返回结果。

图 1. Nutch 总体结构
Nutch 总体结构

Nutch 的运行流程

在了解了 Nutch 的总体结构之后,再详细的看看 Nutch 具体是如何运行的?Nutch 的运行流程如图2所示。

1. 将起始 URL 集合注入到 Nutch 系统之中。

2. 生成片段文件,其中包含了将要抓取的 URL 地址。

3. 根据URL地址在互联网上抓取相应的内容。

4. 解析所抓取到的网页,并分析其中的文本和数据。

5. 根据新抓取的网页中的URL集合来更新起始URL集合,并再次进行抓取。

6. 同时,对抓取到的网页内容建立索引,生成索引文件存放在系统之中。

图 2. Nutch 的运行流程
Nutch 的运行流程

从用户端来看,Nutch 提供了一个基于 Tomcat 的应用程序,它允许用户输入词条,然后 Nutch 会在已经建立好的索引文件中进行搜索,并将相应的结果返回给用户。

Nutch 的配置和运行

Nutch 既可以在 Linux 下运行,可以在 Windows 下运行,同时还可以在 Eclipse 环境中运行。在本部分中,主要介绍如何在 Eclipse 环境下运行 Nutch。

下载 Nuch 软件包

首先,应该在 Nutch 的下载页面中下载相应的Nutch软件包,现在最新的版本号是0.9, 通常使用的版本号是 0.8.1。

解压缩

下载后得到的是一个名为 nutch-0.9.tar.gz 的压缩包,使用7-Zip可以将其解压缩,解压后得到的文件结构如图3所示。

图 3. Nutch 的目录结构
Nutch 的目录结构

在bin文件夹下存放的是用于命令行运行的文件;Nutch的配置文件都放在了conf下,lib是一些运行所需要的jar文件;plugins下存放的相应的插件;在src文件夹中的是Nutch的所有源文件;webapps文件夹中存放的是web运行相关文件;nutch-0.9.war是Nutch所提供的基于Tomcat的应用程序包。

导入源代码

在获得Nutch的源代码之中,就可以将其导入到Eclipse环境中,并生成一个新的java工程。导入后的代码结构如图4所示。在导入过程中应该注意的是,需要把lib下的所有jar文件以及conf文件夹都添加到工程的build path之中。

另外,Nutch还需要另外两个jar文件,jid3lib-0.5.1.jar和rtf-parser.jar,请分到到下面两个链接下载。

http://nutch.cvs.sourceforge.net/nutch/nutch/src/plugin/parse-mp3/lib/

http://nutch.cvs.sourceforge.net/nutch/nutch/src/plugin/parse-rtf/lib/

图 4. Nutch 的包结构
Nutch 的包结构

配置

在正式开始运行Nutch之前,还需要做一些必要的配置,不然在运行时会出错,无法按照要求抓取到相应的页面。

第一个需要修改的文件是 nutch-default.xml, 需要将 HTTP properties 部分的 http.agent.name 赋予一个有意思的字符串;还需要将 plugin properties 部分的 plugin.folders 按照具体的情况做必要修改。清单 1 和清单 2 分别是本文中的 Demo 运行时的具体配置情况,供大家参考。

清单1.
<!-- HTTP properties -->
  <name>http.agent.name</name>
  <value>testNutch</value>
  <description>Just for Testing
  </description>
</property>
清单2.
<!-- plugin properties -->
<property>
  <name>plugin.folders</name>
  <value>plugin</value>
  <description>Directories where nutch plugins are located.  Each
  element may be a relative or absolute path.  If absolute, it is used
  as is.  If relative, it is searched for on the classpath.</description>
</property>

其次,需要修改的文件是crawl-urlfilter.txt, 将其中的MY.DOMAIN.NAME部分按照实际的域名进行修改。清单3中的配置是对*.ibm.com/域进行抓取。

清单3.
# accept hosts in MY.DOMAIN.NAME
+^http://([a-z0-9]*\.)*ibm.com/

另外,还需要的一个操作是在conf文件夹下,建立一个名为prefix-urlfilter.txt的文本文件,其中的内容很简单,如清单4所示。

清单4.
# prefix-urlfilter.txt file starts here
http
# prefix-urlfilter.txt file ends here

抓取

在配置完成之后,就可以开始运行Nutch的Crawler了,不过,正如本文前面所述,开始运行前还需要设定初始URL集合。具体的方法是建立一个文件夹(本文建立的文件夹名为url),并在其中建立一个纯文本文件(本文建立的文件名为urls.txt),文件文件中存放了需要抓取的其实URL地址,如“http://www.ibm.com/”。

然后在org.apache.nutch.crawl包下的Crawl.java文件上点击右键,选择“Run as”,再选择“open run dialog”,在如图5所示的对话框中输入运行参数,然后点击“Run”。这样系统就可以运行了。

图 5. 运行 Crawler
运行 Crawler

在运行过程中,会出现很多的log信息,图6和图7是系统运行过程中的一些截图,从中可以看出正在抓取的网页URL地址和抓取速度等一些信息。等抓取任务成后,系统会自动生成相应的索引文件,以后查询器使用。在以后的文章中,会深入探讨相应的话题。

图 6. Nutch 运行信息 1
Nutch 运行信息 1
图 7. Nutch 运行信息 2
Nutch 运行信息 2

深入分析 Crawl 源代码

在了解了 Nutch 的运行过程之后,再来分析 Nutch 内部的运行流程是什么样子的,以及各个类之间是如何协同配置的?

Crawl的入口

正如在前文中所提到的,在运行 Crawl 时需要输入一些必要的参数,并且格式也是一定的。具体的用法是 Crawl <urlDir> [-dir d] [-threads n] [-depth i] [-topN N]。其中,<urlDir> 是必须有的参数;Crawl 是运行的主文件;-dir 表示存放的目标文件夹;-threads 表示抓取过程中其中的线程数;-depth 表示要抓取的深度层次。

如果在运行时不指定这些参数,那么Nutch会默认设定这个参数值。详见清单。

清单 5.
   Path dir = new Path("crawl-" + getDate());
    int threads = job.getInt("fetcher.threads.fetch", 10);
    int depth = 5;
int topN = Integer.MAX_VALUE;

如果指定了运行参数,Nutch会按照以下的方式来处理。

清单 6.
for (int i = 0; i < args.length; i++) {
      if ("-dir".equals(args[i])) {
        dir = new Path(args[i+1]);
        i++;
      } else if ("-threads".equals(args[i])) {
        threads = Integer.parseInt(args[i+1]);
        i++;
      } else if ("-depth".equals(args[i])) {
        depth = Integer.parseInt(args[i+1]);
        i++;
      } else if ("-topN".equals(args[i])) {
        topN = Integer.parseInt(args[i+1]);
        i++;
      } else if (args[i] != null) {
        rootUrlDir = new Path(args[i]);
      }
}

生成目标文件夹

在设定运行参数后,经过一个必要的处理,Nutch会生成若干个目标文件夹用来存储不同的文件内容,具体包括:crawlDb,linkDb,segments,indexes和index。

清单 7.
    Path crawlDb = new Path(dir + "/crawldb");
    Path linkDb = new Path(dir + "/linkdb");
    Path segments = new Path(dir + "/segments");
    Path indexes = new Path(dir + "/indexes");
Path index = new Path(dir + "/index");

注入、抓取和更新

当生成了所需要的目标文件夹之后,Nutch就可以开始抓取工作了。当然,在抓取网页过程中会使用功能类来完成相应的单元工作。具体来讲,在注入、抓取和更新过程中,会用来的功能类有Injector、Generator、Fetcher、ParseSegment和CrawlDb。

整个过程分为以下几个步骤:

注入
injector.inject(crawlDb, rootUrlDir);
抓取
Path segment = generator.generate(crawlDb, segments, -1, topN, System
          .currentTimeMillis(), false, false);
      if (segment == null) {
        LOG.info("Stopping at depth=" + i + " - no more URLs to fetch.");
        break;
      }
      fetcher.fetch(segment, threads);
更新
if (!Fetcher.isParsing(job)) {
        parseSegment.parse(segment);  
      }
      crawlDbTool.update(crawlDb, new Path[]{segment}, true, true);

4. 反转、索引、去重及合并

最后的工作就是生成索引,去重并合并索引。不过,现在一般都是会生成倒排索引文件,所以在建立索引之前还会有一个反转的操作,如清单所示。

清单 8.
linkDbTool.invert(linkDb, segments, true, true, false); // invert links

      // 索引
      indexer.index(indexes, crawlDb, linkDb, fs.listPaths(segments));
      //去重
      dedup.dedup(new Path[] { indexes });
      //合并
      merger.merge(fs.listPaths(indexes), index, tmpDir);

总结

本文主要介绍了使用Nutch进行网页抓取和建立索引方面的内容,首先分析了网页抓取的过程,然后结合源代码分析了整个抓取过程的组织和实现。当然了,Nutch是一款功能非常丰富的开源搜索引擎,关于其他方面的内容,将在后面的文章中一一介绍。

参考资料




-------------------------------------------------------------------------------------------------------------------------------------------

如果你仅想使用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的IPC系统,调用所有server上的nutchBeans,最后规约出总的结果。

三是每个站点只显示分数最高的一页,如果用户还想看同站的其他结果,就需要访问MoreHitsExculde[]。

四是生成Summary,读取segments目录,按segments和url 获得content, 并按一定算法抽取出包含关键字的文档片断。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值