代码改变世界

介绍Nutch(翻译)

2006-08-28 23:14  cppguy  阅读(1343)  评论(1编辑  收藏  举报

 

介绍Nutch(1)(翻译)[原创]

      Nutch可以分为2个部分:抓取部分和搜索部分。抓取程序抓取页面并把抓取回来的数据做成反向索引,搜索程序则对反向索引搜索回答用户的请求。抓取程序和搜索程序的接口是索引.

     抓取程序是被Nutch的抓取工具驱动的。这是一组工具,用来建立和维护几个不同的数据结构: web database, a set of segments, and the index。下面我们逐个解释上面提到的3个不同的数据结构。

      The web database, 或者WebDB, 是一个特殊存储数据结构,用来映像被抓取网站数据的结构和属性的集合。WebDB 用来存储从抓取开始(包括重新抓取)的所有网站结构数据和属性.WebDB只被抓取程序使用,在搜索程序不被用到.它存储了两种实体:页面和链接.一个页面代表了网络中的一个网页.这个页面通过它的url被索引,同时建立一个对其内容的md5哈希签名.网页中其他的信息也被存储了,包括链接数量(外链接),页面抓取信息(在页面中重复抓取的情况下),还有页面的级别分数(score),这是对一个衡量页面权重的参数(比如一个score高的页面表示它正被很多的页面所连接).  link 表示从一个网页的链接到其它网页的链接.因此WebDb可以看作是一个网络图,结点是网页,边是链接.

      Segment是网页的集合,并且在抓取过程中被索引过了.Segment的fetchlist是抓取程序的 urls 的列表,它是从webDb中生成的.fetcher的输出数据是抓取程序从fetchlist抓取的网页.然后这些数据先被反向索引,并被保存到 Segment中去.Segment的生命周期是有限的.当下一次抓取的时候就没有了,默认的存活期限是30天,所以删除segment是节省磁盘空间的好方法.Segment 的命名是 日期加时间 ,因此很直观的可以看出他们的存活周期.

     index是反向索引所有系统被抓取的页面,他并不直接从页面反向索引产生,它是合并了所有的单个的segment索引.Nutch使用lucene进行索引,所以所有lucene工具和API都可以访问并使用这些建立的索引.需要注意的,Nutch中的Segment和Lucene中Segment是两个完全不同的概念,大家不要混淆.前者是webdb抓取和索引的一部分,而后者是lucene索引的一部分.

   抓取工具

   现在我们已经了解了一些基本概念,那我们先熟悉抓取工具

    抓取是一个循环的过程:抓取蜘蛛从WebDb中生成一个fetchlist的集合;抽取工具根据fetchlist的内容下载关联的网页的内容,同时抓取蜘蛛根据新发现的连接更新webDb,然后再生成一个新的fetchlist的集合;然后周而复始.这个循环可以描述为:生成---抓取----更新-- --循环.

   同一域名的urls往往并合并到同一个fetchlist中,这样可以避免在用多个抓取程序同时运行的时候出现重复抓取的情况.Nutch遵循 Robots Exclusion Protocol.

 下面是crawl tool的一些底层的工具名和相关动作:

1:新建一个WebDB(admin db -create)

2:把起始的根url放入WebDB(inject)

3:在WebDB的一个新Segment中生成一个fetchlist(generate)

4:根据fetchlist的url抓取相关网页内容(fetch)

5:根据抓取回来的网页链接url更新 WebDB(updatedb)

6:重复上面3-5个步骤直到到达指定的抓取层数

7:根据计算出来的网页权重scores和webDb中的连接更新segement(updatesegs)

8:索引抓取的网页(index)

9:在索引中消除重复的内容和重复的url (dedup)

10:合并多个索引为一个大的单独的索引,为搜索建立索引库(merge)

运行一个网络爬虫

首先下载一个最新版本的nutch,解压.这里假设为linux环境下并安装有java虚拟机

 这里创建一个抓取的例子,有四个页面需要被索引,网页的结构如图

 

在运行网络爬虫前,先新建一个名叫urls的文本文件,里面有根url(最先开始爬行的url),这里我们从page A开始

echo 'http://keaton/tinysite/A.html' > urls

网络爬虫通过一个筛选器来决定需要抓取的网页的url,这里是通过一个正则表达式来描述url必须遵循的模式,操作为修改conf/crawl-urlfilter.txt这个配置文件: 

+^http://([a-z0-9]*\.)*MY.DOMAIN.NAME/

to

+^http://keaton/
运行爬虫命令:
bin/nutch crawl urls -dir craw-tinysite -depth 3>&crawl.log
网络爬虫使用urls中的根url来作为起点,把结果存入crawl-tinysite这个目录下,
把活动的日志写入crawl.log文件中,-depth表示爬行的深度
 
查看爬行结果 
 
Nutch还附带了几个查看其创建的数据结构的工具,我们可以用他们来查看刚才网络爬虫生成了什么东西
 
WebDB
首先我们查看数据库里网页和链接的数目.使用它可以验证网络爬虫是否抓取过网页了,抓取了多少.工具readdb对webDB分析并输出其中的数据.
1
bin/nutch readdb crawl-tinysite/db -stats
输出结果
Number of pages: 4
Number of links: 4
 注意命令行最后的选项 -stats
2:如果用-dumpageurl
bin/nutch readdb crawl-tinysite/db -dumppageurl
输出结果
Page 1: Version: 4
URL: http://keaton/tinysite/A.html
ID: fb8b9f0792e449cda72a9670b4ce833a
Next fetch: Thu Nov 24 11:13:35 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 1
Score: 1.0
NextScore: 1.0


Page 2: Version: 4
URL: http://keaton/tinysite/B.html
ID: 404db2bd139307b0e1b696d3a1a772b4
Next fetch: Thu Nov 24 11:13:37 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 3
Score: 1.0
NextScore: 1.0


Page 3: Version: 4
URL: http://keaton/tinysite/C-duplicate.html
ID: be7e0a5c7ad9d98dd3a518838afd5276
Next fetch: Thu Nov 24 11:13:39 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 0
Score: 1.0
NextScore: 1.0


Page 4: Version: 4
URL: http://keaton/tinysite/C.html
ID: be7e0a5c7ad9d98dd3a518838afd5276
Next fetch: Thu Nov 24 11:13:40 GMT 2005
Retries since fetch: 0
Retry interval: 30 days
Num outlinks: 0
Score: 1.0
NextScore: 1.0
这样可以比较直观的查看每页,需要注意的是:ID是对相对网页内容的md5哈希签名,所以说c和c_duplicate具有相同的ID,说明其内容是完全一样的.
3:
bin/nutch readdb crawl-tinysite/db -dumplinks
输出结果:
from http://keaton/tinysite/B.html
to http://keaton/tinysite/A.html
to http://keaton/tinysite/C-duplicate.html
to http://keaton/tinysite/C.html

from http://keaton/tinysite/A.html
to
http://keaton/tinysite/B.html
查看网络图的结构
 
还有其他的命令来查看其他样式的内容,这里不再详述了.我们可以通过查看nutch的源码和api,org.apache.nutch.db.WebDBReader,
这里面包含了实现readdb的java 类
Segments

Crawler在抓取中共生成了三个segment,分别存放于segments文件夹下的以时间戳为文件夹名的三个子文件夹下面。

每个segment代表Crawler的一次“产生/抓取/更新”循环。Nutch中提供了如下的命令可以清晰的看到segments的简介:

 

bin/nutch segread -list -dir crawl-tinysite/segments/

命令结果如下所示:

PARSED? STARTED           FINISHED          COUNT DIR NAME

 

true    20051025-12:13:35 20051025-12:13:35 1     crawl-tinysite/segments/20051025121334

 

 

 

true    20051025-12:13:37 20051025-12:13:37 1     crawl-tinysite/segments/20051025121337

 

 

 

true    20051025-12:13:39 20051025-12:13:39 2     crawl-tinysite/segments/20051025121339

 

 

 

TOTAL: 4 entries in 3 segments.

 

结果中PARSED?列表示的是在抓取之后是否接着进行解析和索引,默认的都是true。但是如果你利用底层命令进行抓取操作的时候,

你可以在抓取之后独立地再另外进行解析和索引工作,此时此列才会为falseSTARTEDFINISHED两列记录的是此循环的开始时间和结束时间,

这些信息可以帮助用户分析那些抓取时间过长的页面是怎么回事。COUNT列代表的是此segment内包含的被抓取回来的网页数目,

例如最后一个segment此列值为2,代表的是segment中有两个被抓取回来的网页,即C网页和C-dup网页。

 

但是这些简介信息并不够详细,下面的命令可以可以更清楚的看到单个segment的详细信息,我们以第一个segment为例:

 

s=`ls -d crawl-tinysite/segments/* | head -1`

 

bin/nutch segread -dump $s

结果为:

Recno:: 0

 

FetcherOutput::

 

FetchListEntry: version: 2

 

fetch: true

 

page: Version: 4

 

URL: http://keaton/tinysite/A.html

 

ID: 6cf980375ed1312a0ef1d77fd1760a3e

 

Next fetch: Tue Nov 01 11:13:34 GMT 2005

 

Retries since fetch: 0

 

Retry interval: 30 days

 

Num outlinks: 0

 

Score: 1.0

 

NextScore: 1.0

 

 

 

anchors: 1

 

anchor: A

 

Fetch Result:

 

MD5Hash: fb8b9f0792e449cda72a9670b4ce833a

 

ProtocolStatus: success(1), lastModified=0

 

FetchDate: Tue Oct 25 12:13:35 BST 2005

 

 

 

Content::

 

url: http://keaton/tinysite/A.html

 

base: http://keaton/tinysite/A.html

 

contentType: text/html

 

metadata: {Date=Tue, 25 Oct 2005 11:13:34 GMT, Server=Apache-Coyote/1.1,

 

Connection=close, Content-Type=text/html, ETag=W/"1106-1130238131000",

 

Last-Modified=Tue, 25 Oct 2005 11:02:11 GMT, Content-Length=1106}

 

Content:

 

<?xml version="1.0" encoding="UTF-8"?>

 

<!DOCTYPE html

 

 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

 

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

 

<head>

 

<title>'A' is for Alligator</title>

 

</head>

 

<body>

 

<p>

 

Alligators live in freshwater environments such as ponds,

 

marshes, rivers and swamps. Although alligators have

 

heavy bodies and slow metabolisms, they are capable of

 

short bursts of speed that can exceed 30 miles per hour.

 

Alligators' main prey are smaller animals that they can kill

 

and eat with a single bite. Alligators may kill larger prey

 

by grabbing it and dragging it in the water to drown.

 

Food items that can't be eaten in one bite are either allowed

 

to rot or are rendered by biting and then spinning or

 

convulsing wildly until bite size pieces are torn off.

 

(From

 

<a href="http://en.wikipedia.org/wiki/Alligator">the

 

Wikipedia entry for Alligator</a>.)

 

</p>

 

<p><a href="B.html">B</a></p>

 

</body>

 

</html>

 

 

 

ParseData::

 

Status: success(1,0)

 

Title: 'A' is for Alligator

 

Outlinks: 2

 

outlink: toUrl: http://en.wikipedia.org/wiki/Alligator

 

anchor: the Wikipedia entry for Alligator

 

outlink: toUrl: http://keaton/tinysite/B.html anchor: B

 

Metadata: {Date=Tue, 25 Oct 2005 11:13:34 GMT,

 

CharEncodingForConversion=windows-1252, Server=Apache-Coyote/1.1,

 

Last-Modified=Tue, 25 Oct 2005 11:02:11 GMT, ETag=W/"1106-1130238131000",

 

Content-Type=text/html, Connection=close, Content-Length=1106}

 

 

 

ParseText::

 

'A' is for Alligator Alligators live in freshwater environments such

 

as ponds, marshes, rivers and swamps. Although alligators have heavy

 

bodies and slow metabolisms, they are capable of short bursts of

 

speed that can exceed 30 miles per hour. Alligators' main prey are

 

smaller animals that they can kill and eat with a single bite.

 

Alligators may kill larger prey by grabbing it and dragging it in

 

the water to drown. Food items that can't be eaten in one bite are

 

either allowed to rot or are rendered by biting and then spinning or

 

convulsing wildly until bite size pieces are torn off.

 

(From the Wikipedia entry for Alligator .) B

 

可以看到结果中有多个数据块,但是不要弄错,这些数据块都是属于一个网页实体的,那就是A网页。

只不过这些数据块属于不同的种类,是不同的阶段Crawler所得到的A网页的数据。数据总共是三种:fetch dataraw contentpared content

Fetch data被放置于FetcherOutput标识段之内,这些dataCrawler在“产生/抓取/更新”循环的更新阶段为了更新WebDB写入WebDB中的关于A网页的数据。

 

Raw content被放置于Content标识段之内,是Fetcher从网络上抓取的网页的原始文本数据,包括了完整的网页头数据和网页体。

默认的是通过http协议插件进行下载此数据。这些数据当你设置nutch拥有网页快照能力的时候被保存。

 

最后,Raw content被解析模块进行解析生成parsed content,解析模块在Nutch中是以插件的形式进行实现的,根据下载网页的格式决定利用哪个插件进行解析。

Parsed content被放置于ParseDataParseText标识段之内,它被用于建立segment的索引

index
通过luke查看所生成的索引
   从上图中看到pageA被索引之后生成的Field,这里引起注意的是boost field.它描述了此网页被其他网页连接的数目偏差值.
此网页链接的网页越多,它的boost的值就越高.公式ln(e+n)计算boost的值,其中n的值是链接的数目.在我们这个例子中,Page B只被A链接,所以
只有一个inboud link,boost=ln(e+1)=1.3132616 ...
   也许你问到,boost field与WebDB和segment的抓取输出流中的score有怎样的关系呢?其实boost=scores*(ln(e+n)),
只不过对于我们的网络爬虫来说,socres总是1.0.
  那么什么时候scores不等于1.0呢?Nutch还附带了一个LinkAnalysisTool的工具,它使用了类似于google的PageRank的算法.但是对于连接的分析不是必要的,
所以这也不是网络爬虫的必备程序,
但是对与全球网页的通用搜索引擎来说是很重要的,所以google的成功也得意于PageRank
 
 

Resources

  • The Nutch project page is the place to start for more information on Nutch. The mailing lists for nutch-user and nutch-dev are worth searching if you have a question.
  • At the time of this writing, the Map Reduce version of Nutch is in the main trunk and is not in a released version. This means that you need to build it yourself if you want to use it (or wait for version 0.8 to be released).
  • For more on whole-web crawling, see the Nutch tutorial.
  • For more information on Nutch plugins (which are based on the Eclipse 2.0 plugin architecture), a good starting point is PluginCentral on the Nutch Wiki.
  • Creative Commons provides a Nutch-powered search option for finding Creative-Commons-licensed content (see also this blog entry).
  • " Building Nutch: Open Source Search" (ACM Queue, vol. 2, no. 2, April 2004), by Mike Cafarella and Doug Cutting, is a good high-level introduction to Nutch.
  • "Nutch: A Flexible and Scalable Open Source Web Search Engine" (PDF) (CommerceNet Labs Technical Report 04-04, November 2004), by Rohit Khare, Doug Cutting, Kragen Sitaker, and Adam Rifkin, covers the filesystem scale of Nutch particularly well.