首页 > Linux云计算/云主机/虚拟化技术/系统架构 > nutch简介(nutch原理&nutch+solr抓取并索引网页的配置)

nutch简介(nutch原理&nutch+solr抓取并索引网页的配置)

2015年5月23日

nutch简介(nutch原理&nutch+solr抓取并索引网页的配置)

http://yuebingzhang.elastos.org/2013/08/01/nutch%E7%AE%80%E4%BB%8Bnutch%E5%8E%9F%E7%90%86nutchsolr%E6%8A%93%E5%8F%96%E5%B9%B6%E7%B4%A2%E5%BC%95%E7%BD%91%E9%A1%B5%E7%9A%84%E9%85%8D%E7%BD%AE/

nutch简介

Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具(包括全文搜索和Web爬虫)。当然我们也可以将nutch和solr配合起来使用,nutch实现爬虫并且将数据索引添加到solr的数据库中,由solr负责查询工作。

nutch原理

Nutch主要分为两个部分:爬虫crawler和查询searcher。Crawler主要用于从网络上抓取网页并为这些网页建立索引。Searcher主要利用这些索引检索用户的查找关键词来产生查找结果。两者之间的接口是索引,所以除去索引部分,两者之间的耦合度很低。

也正是由于爬虫和查询两个部分的耦合度很低,我们可以用solr来实现查询部分的功能,所以下面我们只介绍nutch爬虫crawler的原理。

爬虫crawler

我们先来介绍crawler的存储数据的文件结构:

crawler数据文件主要包括三类,分别是web database,一系列的segment加上index,三者的物理文件分别存储在爬行结果目录下的db目录下webdb子文件夹内,segments文件夹和index文件夹。(对于nutch1.7,文件结构有所不同,每次爬虫后,会在nutch根目录下产生一个名为“crawler+年+月+日+时+分+秒”的文件夹,里面存储的就是这次爬虫产生的所有数据文件,文件夹内部的不同之处我们在下面的详细介绍中加以说明)三者存储的信息内容如下:

Web database,也叫WebDB,其中存储的是爬虫所抓取网页之间的链接结构信息,它只在爬虫Crawler工作中使用而和Searcher的工作没有任何关系。WebDB内存储了两种实体的信息:page和link。Page实体通过描述网络上一个网页的特征信息来表征一个实际的网页,因为网页有很多个需要描述,WebDB中通过网页的URL和网页内容的MD5两种索引方法对这些网页实体进行了索引。Page实体描述的网页特征主要包括网页内的link数目,抓取此网页的时间等相关抓取信息,对此网页的重要度评分等。同样的,Link实体描述的是两个page实体之间的链接关系。WebDB构成了一个所抓取网页的链接结构图,这个图中Page实体是图的结点,而Link实体则代表图的边。(我在实践中使用的是nutch1.7+solr4.4,其中将WebDB分为crawlerdb和linkdb两个部分)

一次爬行会产生很多个segment,每个segment内存储的是爬虫Crawler在单独一次抓取循环中抓到的网页以及这些网页的索引。Crawler爬行时会根据WebDB中的link关系按照一定的爬行策略生成每次抓取循环所需的fetchlist,然后Fetcher通过fetchlist中的URLs抓取这些网页并索引,然后将其存入segment。Segment是有时限的,当这些网页被Crawler重新抓取后,先前抓取产生的segment就作废了。在存储中。Segment文件夹是以产生时间命名的,方便我们删除作废的segments以节省存储空间。

Index是Crawler抓取的所有网页的索引,它是通过对所有单个segment中的索引进行合并处理所得的。Nutch利用Lucene技术进行索引,所以Lucene中对索引进行操作的接口对Nutch中的index同样有效。但是需要注意的是,Lucene中的segment和Nutch中的不同,Lucene中的segment是索引index的一部分,但是Nutch中的segment只是WebDB中各个部分网页的内容和索引,最后通过其生成的index跟这些segment已经毫无关系了。(由于我们使用solr来实现查询,所以在nutch的数据文件中找不到index这个文件夹,它被存入到solr的文件目录下)

在清楚了crawler的文件结构后,我们来介绍crawler的工作流程:

Crawler的工作原理主要是:首先Crawler根据WebDB生成一个待抓取网页的URL集合叫做Fetchlist,接着下载线程Fetcher开始根据Fetchlist将网页抓取回来,如果下载线程有很多个,那么就生成很多个Fetchlist,也就是一个Fetcher对应一个Fetchlist。然后Crawler根据抓取回来的网页WebDB进行更新,根据更新后的WebDB生成新的Fetchlist,里面是未抓取的或者新发现的URLs,然后下一轮抓取循环重新开始。这个循环过程可以叫做“产生/抓取/更新”循环。

指向同一个主机上Web资源的URLs通常被分配到同一个Fetchlist中,这样的话防止过多的Fetchers对一个主机同时进行抓取造成主机负担过重。另外Nutch遵守Robots Exclusion Protocol,网站可以通过自定义Robots.txt控制Crawler的抓取。

在Nutch中,Crawler操作的实现是通过一系列子操作的实现来完成的。这些子操作Nutch都提供了子命令行可以单独进行调用。下面就是这些子操作的功能描述以及命令行,命令行在括号中。

1. 创建一个新的WebDb (admin db -create).

2. 将抓取起始URLs写入WebDB中 (inject).

3. 根据WebDB生成fetchlist并写入相应的segment(generate).

4. 根据fetchlist中的URL抓取网页 (fetch).

5. 根据抓取网页更新WebDb (updatedb).

6. 循环进行3-5步直至预先设定的抓取深度。

7. 根据WebDB得到的网页评分和links更新segments (updatesegs).

8. 对所抓取的网页进行索引(index).

9. 在索引中丢弃有重复内容的网页和重复的URLs (dedup).

10. 将segments中的索引进行合并生成用于检索的最终index(merge).

Crawler详细工作流程是:在创建一个WebDB之后(步骤1), “产生/抓取/更新”循环(步骤3-6)根据一些种子URLs开始启动。当这个循环彻底结束,Crawler根据抓取中生成的segments创建索引(步骤7-10)。在进行重复URLs清除(步骤9)之前,每个segment的索引都是独立的(步骤8)。最终,各个独立的segment索引被合并为一个最终的索引index(步骤10)。

nutch1.7+solr4.4配置

从Nutch 网站下载apache-nutch-1.7-bin.tar.gz 回来解开(~/apache-nutch-1.7/)

把Solr 预设的core 范例collection1 复制为core-nutch

把Nutch 提供的conf/schema-solr4.xml 覆盖掉Solr core-nutch 的conf/schema.xml

将Solr core-nutch conf/schema.xml补上一行漏掉的栏位设定<field name=”_version_” type=”long” stored=”true” indexed=”true” multiValued=”false”/>

重开Solr,进Web管理介面的Core Admin新增一个core-nutch core,并且不该有这个新增core的错误讯息。

回来~/apache-nutch-1.7/ 设定Nutch。 conf/ 底下先编辑nutch-site.xml 补上http.agent.name 的crawler 名称设定。

再编辑regex-urlfilter.txt将最后一行+.注解掉,改为+^http://my.site.domain.name只抓我自己的网站

再回到~/apache-nutch-1.7/,新增一个urls/ 目录,里头放一个seed.txt,内容放自己想要抓的种子网址,这里因为只想要抓自己的网站,所以只要放一行http://my.site.domain.name/就好

接下来跑./bin/nutch crawl urls/ -solr http://solr.server.name/solr/core-nutch/ -threads 20 -depth 2 -topN 3测试能不能抓到网站上层的几个网页,到Solr 管理介面里头用查询功能如果有资料,就是成功了。

下面是我抓取一个博客网站和php.net的截图:

Screenshot-from-2013-08-01-155016

 

 

本文的评论功能被关闭了.