`
wwkevin811
  • 浏览: 6494 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

Nutch源代码解读--1

阅读更多
主要分析利用HTTP协议爬取爬取网页)

   本身是研究搜索引擎地,对开源的NUTCH很感兴趣。但是网上的代码对于NUTCH的分析都十分有限,我希望能尽我的力量把NUTCH里的代码尽我所能分析给大家。

本文主要从一个爬虫系统最底层的爬虫如何爬行一个网页做一个分析。这个是比较底层的,如果之前对NUTCH没有详细使用过或者看过一些代码的。可以先去网上看一些使用NUTCH的流程。再看我这里的分析,可能会更加清楚些。

  (PS:Nutch的官方http://lucene.apache.org/nutch/,much more details)

  OK:话归正题.nutch里通过fecher这个类具体负责一次的爬行工作。在Crawl这个main方法里   fetcher.fetch(segment, threads); // fetch it这里的segment是经过处理的包含了待爬行队列的URL的信息。(这在以后会更详细的介绍到),threads是准备进行爬行的爬虫个数,就是使用几个线程来爬取segment里的url.在fecher.fecth()这个方法,

for (int i = 0; i < threadCount; i++) {       // spawn threads

      new FetcherThread(getConf()).start();}

最终执行的过程是由FetcherThread这个内部类的run方法执行地。那么它如何爬取网页的呢?

       Protocol protocol = this.protocolFactory.getProtocol(url.toString());

     ProtocolOutput output = protocol.getProtocolOutput(url, datum);

     ProtocolStatus status = output.getStatus();

    Content content = output.getContent();

在RUN方法里执行爬取网页的主要代码就是上面4行。简单地说这里的url是从刚才的segment里获取的相关爬行url的信息。

第一:获得了这个URL的使用的协议。本文主要介绍http协议。(看完下面你对HTTP协议,也会有帮助地)

第二:利用这个协议,获得响应的内容。第三:内容的相关状态。第四:内容里的实质性内容获取

下面是具体地分析:我们知道NUTCH里的大部分东西是通过插件开发的。那么这里PROTOCAL只是一个接口,定义了一个普通的协议接口,具体的协议如HTTP协议是以插件包形式发布地。下面主要分析地就是HTTP协议。

类都在package org.apache.nutch.protocol.http里面。大概的流程就是HTTP类利用HTTP协议产生一个HTTPRESPONSE类,利用HttpResponse类里的Content和返回的状态码产生一个PROTALOUTPUT类。这就是我们第二步的大概流程。也是底下分析的关键。

关键代码就是上面地getProtocalOutput(url,crawlDatum)是怎么运作地。分析代码如下:     

getProtocal()方法的主体框架:

getProtocal()方法的主体框架:

URL u = new URL(urlString);

   if (checkRobots) {

        //处理是否有设置了robot.txt检查,如果有进行相应地检查包括了是否允许反问这个IP}

      long crawlDelay = robots.getCrawlDelay(this, u);//根据robot.txt设置这个爬虫的等待时间

      long delay = crawlDelay > 0 ? crawlDelay : serverDelay;//如果没有设置,则等于serverdelay

      if (checkBlocking && maxCrawlDelay >= 0 && delay > maxCrawlDelay) {

      //如果爬虫的等待时间,超过了预先设置的最大等待时间那么忽略这个URL

} . . .

      //是否设置了检查block,因为多线程爬虫时,对一个IP可能只允许一只爬虫,如果另外的爬虫也进来了,那么它就应该被block了.会被放入一个Block_List中进行等待.涉及多线程对同步变量的返问.

      if (checkBlocking) {

        //对于爬虫是否被block进行相应地处理,如果被block次数大于maxDelays那么就自动取消它的任务了,会抛出一个异常

      }

      //当爬虫不被block时,获取它的输出

      Response response;

      try {

        response = getResponse(u, datum, false); // make a request

      } finally {

        //改爬虫对该ip返回完毕,解除BLOCK,让其他的爬虫可以返问.

        if (checkBlocking) unblockAddr(host, delay);

      }

      //根据返回的状态码进行相应地处理,底下一般大家都能看懂了

      int code = response.getCode();

     . . .

      if (code == 200) { // got a good response

        return new ProtocolOutput(c); // return it

       

      } else if{

      ....

      }

2 getResponse()的程序框架:方法返回一个HttpResponse的对象.(哭!!!百度对文章长度限制,我贴代码太长了)只能做个简要分析了。这个构造方法就是利用url的信息,建立一个socket发出一个get的请求,然后通过返回的消息内容,设置关于这个url的datum里的Metadata信息,以及读取网页里的内容保存在Content里。从而返回的HttpResponse就有了关于url的网页的相关信息了。到此就完成了一个网页的抓取了。呵呵,可见了解底层的一些协议还是很关键地,比如:

1 HTTP 1.1协议里的状态码表示什么? 200:成功;300-400:表示重定向了,

400 Bad Request;401 未授权;404 未找到;410 网页不存在permanently gone;

2 了解一个HTTP请求报头,和响应的报头也是很基本的知识。

截取几个报头,学习:

      GET / HTTP/1.0

Host: www.xmu.edu.cn

Accept-Encoding: x-gzip,gzip

User-Agent: mynutch/Nutch-0.9

这个是我的nutch对厦门大学主页发起的一个请求.可以看到这是一个Get请求,HTTP1.0协议地,请求的主机名。使用的压缩方式,用户返问的agent.(如果是浏览器,那么这里可是会显示浏览器的型号),还有其他的报头,比如connection是否进行长连接,referer是否是其他连接过来地,cookie请求的cookie。

下面是一个响应的报头:

    HTTP/1.1 200 OK

    Connection:close

Date: Sun, 25 May 2008 11:12:28 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

Content-Length: 12006

Content-Type: text/html

Set-Cookie: ASPSESSIONIDQABRDBRR=LALGDJHAFMFCLAPDOONBLLOK; path=/

Cache-control: private

0
8
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics