2.1.2 Apache Nutch简介
“小明哥,什么是Apache,什么是Nutch?”
“嗯,我们先介绍Apache吧,后面的章节中会多处提及与其相关的开源项目。”
这里Apache是Apache软件基金会(Apache Software Foundation,ASF),及与其对应的开源社区、开源项目的统称。Apache基金会是一个非营利性的组织,正式创建于1999年7月,专门为开源软件项目的Apache团体提供运作支持。这个组织将自己定义为有着相同目标的开发者与用户团体,而不只是简单地共享在一个服务器上的一组项目。在它所支持的Apache项目与子项目中,所发行的软件产品都遵循Apache许可证。起初,这个组织的开发爱好者们聚集在一起,在美国伊利诺伊斯大学超级计算机应用程序国家中心开发的NCSA HTTPd服务器的基础上,开发与维护了一个名为Apache的HTTP服务器。由于需求的不断扩大,以Apache HTTP服务器为中心,Apache社区启动了更多的并行项目,而这些项目也随着时间的推移、形势的变化而不断地启动、终止、拆分及合并。时至今日,Apache旗下的开源项目众多,应用范围非常之广。除了即将介绍的Nutch以外,在之后的数据存储、处理、信息检索、数据挖掘甚至是效能评估中,都会有相关的项目提及,Apache社区对当下IT领域的影响力可见一斑。
本书介绍的第一个Apache项目是Nutch(http://nutch.apache.org/)。它是一个开源的、基于Java编程语言实现的搜索引擎,诞生于2002年8月,目前最新的版本分别是1.11和2.3。为什么会有两个最新版本?原因是自版本1.2之后,Nutch进一步演化为两大分支版本:1.X和2.X,这两大分支最大的区别在于2.X对底层的数据存储进行了抽象,以支持各种底层存储技术,其中包括Apache的Hadoop、HBase和Solr等主流的存储和查询方案。Nutch的发展超过10年,对于软件行业而言并不算年轻。但是,在Nutch的进化过程中,还衍生了Hadoop、Tika、Gora和Crawler Commons四个重量级的Java开源项目。你没听错,还有Hadoop哦!Hadoop是近几年最为红火的大数据关键词,已成为大规模数据处理事实上的标准之一。因此,从宏观发展的意义而言,Nutch的贡献绝不只限于网络爬虫那么简单。
此外,从功能的角度出发,Nutch也不仅仅是一个爬虫系统,它还提供了运行搜索引擎所需的主要工具,包括全文索引和搜索。相对于那些商用的搜索引擎,Nutch作为开放源代码的搜索引擎,系统架构更加透明,可定制化功能也更加强大,是入门学习的不错选择,其主要组成部分为爬虫(Crawler)、索引器(Indexer)和查询器(Searcher)。爬虫主要用于从网络上抓取网页并为这些网页建立索引,查询器主要是利用这些索引检索用户的查找关键词来产生查找结果,两者之间的接口是索引。如果想深入了解索引和查询的概念,可以先参考第5章的信息检索内容,里面有更为详尽的介绍和探讨。这里主要介绍爬虫相关的部分:涉及的数据文件,以及工作流程。
数据文件主要包括三类,分别是网络数据库(Web Database)、分段(Segment)和索引(Index),三者的物理文件存储在爬行结果目录下的db目录中,分别以WebDB、segments和index命名对应的子文件夹。Web Database,也称WebDB,其所存储的是网页(Page)和链接(Link)实体。网页实体通过描述某个网页的特征信息来表征一个实际的网页。网页富含很多描述信息,为了提高效率,WebDB中通过网页的链接URL和网页内容的MD5(Message Digest Algorithm MD5)两种方法对其进行标识。网页实体描述的网页特征主要包括网页内的链接数目、对此网页的重要度评分、抓取此网页的时间等相关信息。此外,链接实体描述的是两个网页实体之间的链接关系。WebDB构成了一个所抓取网页的链接结构图,其中网页实体是图的结点,而链接实体则代表图的边。这就是我们上节所提到的网络图(Web Graph),对于链接分析非常关键。
爬虫的每次爬行都会产生很多个分段,每个分段内存储的是爬虫在单独一次抓取循环中抓到的网页。爬虫抓取时会按照一定的策略,从WebDB的链接关系中生成每次抓取循环所需的待抓取列表(Fetchlist),然后抓取者(Fetcher)通过该列表中的URL抓取这些网页并进行处理,然后将其存入分段。分段是有时限的,当这些网页被重新抓取后,之前抓取产生的分段就过期了。在具体的存储中,分段的文件夹是以产生的时间来命名的,方便我们删除过期的作废的文件以节省存储空间。
索引器会为所有抓取到的网页创建索引,它是通过对所有单个分段中的索引进行合并处理来得到的。Nutch利用Lucene技术进行索引,Lucene中对索引进行操作的接口对Nutch中的index同样有效。值得注意的是,Lucene的系统里也有分段的概念,但是与Nutch中的分段概念是完全不同的。Lucene中的分段是索引的一部分,而Nutch中的分段只是用于存储WebDB中各个部分的网页内容。
到目前为止,本章已数次提到了Lucene,那么它是什么?与Nutch又有怎样的关系呢?在浏览Nutch的工作流程之前,我们先回答这两个问题。Apache的Lucene是一个开放源代码的全文检索引擎程序库,近几年非常受欢迎。其本身不是一个完整的搜索引擎,而是为软件开发人员提供的一个简单易用的工具包,可用于在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文搜索引擎。Nutch在Lucene的基础之上做了进一步的扩展和封装,增加了爬虫的功能,同时还利用Lucene提供了文本索引和搜索的接口。因此,我们可以简单地理解为,Nutch是一个可以直接运行的搜索引擎,不需要自己编写任何代码就能实现简单的全文搜索功能。不过,本章的重点是介绍网络爬虫,因此这里主要聚焦在Nutch获取数据的部分。对Lucene的使用细节有兴趣的读者可以参见第5章的相关内容。
在分析了爬虫工作中涉及的文件之后,接下来看看其抓取流程及这些文件在抓取过程中所扮演的角色。首先爬虫根据WebDB生成一个待抓取网页的URL集合Fetchlist,接着抓取者线程Fetcher根据Fetchlist将网页抓取回来,如果下载线程有很多个,那么就生成很多个Fetchlist,每个Fetcher对应一个Fetchlist。然后爬虫用抓取回来的网页更新WebDB,根据更新后的WebDB生成新的Fetchlist,里面是尚未抓取的或新发现的网页链接,然后下一轮抓取循环开始。下面是这些子操作的功能描述及执行步骤,括号中是最基本的命令行。
1)创建一个新的WebDB(admin db-create)。
2)将抓取起始链接写入WebDB中(inject)。
3)根据WebDB生成Fetchlist并写入相应的分段(generate)。
4)根据Fetchlist中的链接抓取网页(fetch)。
5)根据抓取网页更新WebDB(updated)。
6)循环进行第3至第5步,直至预先设定的抓取深度或宽度,具体情况视获取策略而定。
7)根据WebDB得到的网页评分和链接来更新分段(updatesegs)。
8)对所抓取的网页进行索引(index)。
9)在索引中丢弃有重复内容的网页和重复的链接(dedup)。
10)将Lucene索引分段中的数据进行合并,生成用于检索的最终索引(merge)。
至此,我们了解了Nutch的工作模块和核心流程,可以看出它是非常标准的爬虫实现。同时,也要看到Nutch并不局限于爬虫,对于索引和查询的相关内容,我们可以放到第5章了解。