nutch2二次开发笔记

1.Nutch介绍

    Nutch 是一个开源Java 实现的爬虫框架和搜索引擎。支持分布式处理,有两个主版本1.x和2.x,它们的主要区别是1.x版本底层存储使用的是HDFS,2.x引入了Gora作为存储抽象层,从而支持各种NoSQL数据库,如HBase,Cassandra等,另外也支持mysql

2.Nutch安装问题

      具体的安装步骤可以参考http://blog.csdn.net/lzjzy520/article/details/41596893,这里仅补充自身遇到的几个问题.

      一.2.3.1版本ant编译时候, 会卡在 loading settings :: file = /usr/java/apache-nutch-2.3.1/ivy/ivysettings.xml,等待很久没反应, 因此选择了安装2.2.1版本

      二.ant编译过程较久,我第一次编译成功花了40多分钟,所以得耐心等待

      三.我是在不修改maven仓库地址的情况下编译成功,仓库地址修改为http://mirrors.ibiblio.org/maven2/或者http://maven.oschina.net/content/groups/public/时编译失败,如果jar包下载不了,可以试试来回切换仓库地址或者使用阿里云的maven仓库地址

      四.linux环境下安装,nutch版本使用2.2.1,solr版本使用4.4.0,hbase版本使用0.90.4

3.Nutch的二次开发

        一.添加cookie抓取需要登录的网站

               首先,将nutch源码导入到eclipse. nutch安装目录下列称为NUTCH_HOME,另外,以尽量少改动源码和写自定义插件的前提下开发

            NUTCH_HOME/runtime/local/conf/nutch-site.xml文件,添加

	
	  plugin.includes
	  protocol-http|protocol-httpclient|urlfilter-regex|parse-(html|tika|metatags)|filter-xpath|index-(basic|metadata|anchor|more)|scoring-opic|urlnormalizer-(pass|regex|basic)|language-identifier
	  Regular expression naming plugin directory names to
	  include.  Any plugin not matching this expression is excluded.
	  In any case you need at least include the nutch-extensionpoints plugin. By
	  default Nutch includes crawling just HTML and plain text via HTTP,
	  and basic indexing and search plugins. In order to use HTTPS please enable
	  protocol-httpclient, but be aware of possible intermittent problems with the
	  underlying commons-httpclient library.
	  
	
            可以将cookie信息也放在这个文件中,如添加

	
		cookie.value
		BAIDUID=24B253A73C44B95F9D0A876F23FCAAAA:FG=1;BDSVRTM=0
	
              接下来,修改源码src/plugin/protocol-httpclient/src/java/Http.java,

             在setConf()方法添加cookieValue变量读取cookie值,在configureClient()方法给header添加Cookie

	public void setConf(Configuration conf) {
	        //其他代码略.....
		cookieValue = conf.get("cookie.value", "");
		//其他代码略....
       }

        private void configureClient() {
               //....
               headers.add(new Header("Cookie", cookieValue));
               //....
        }
      

            二.如果要抓取的页面有分页,但是页码的跳转是用js方法

                  nutch会收集当前页面的url,那么如何将我们自己要想的url添加进去呢?

             首先解析要抓取页面,一共有多少分页.可以找到这个类src/plugin/parse-html/src/java/HtmlParser.java

             getParse(String url, WebPage page)方法中,

         utils.getText(sb, root);          // extract text
         text = sb.toString();             //这里的text就是页面的文本内容
             我们可以看到在DOMContentUtils.getTextHelper()方法遍历了dom节点,通过使用DOM方法获取到总页数,然后可以组装好

       url,在NUTCH_HOME/runtime/local/urls/目录下生产存放url地址的文件. 就是说,让nutch在下一次抓取时候,去访问你这次的url.

             另外,也可以在HtmlParser.java的sniffCharacterEncoding(ByteBuffer content) 方法,str变量是整个页面的html代码,可以用              jsoup进行解析.

             如果不想将url保存到文件中,还有一个思路就是将url更新到crawldb中,看下HtmlParser类中如下的2行代码

       utils.getOutlinks(baseTag!=null?baseTag:base, l, root);
       outlinks = l.toArray(new Outlink[l.size()]);
             我们可以添加自己的url到outlinks集合中.

             三.不想深度抓取

                  默认情况下,nutch会保存抓取页面中的一些HTML标签href属性的url,下次执行命令时候就会抓取这些链接地址.有时候我们并不需要这些额外的数据.这种情况下HtmlParser类的outlinks变量就不需要处理了.

             保存outlinks的代码在src/java/crawl/DbUpdateMapper的map方法

    Map outlinks = page.getOutlinks();
    if (outlinks != null) {
      for (Entry e : outlinks.entrySet()) {
                int depth=Integer.MAX_VALUE;
        Utf8 depthUtf8=page.getFromMarkers(DbUpdaterJob.DISTANCE);
        if (depthUtf8 != null) depth=Integer.parseInt(depthUtf8.toString());
        scoreData.add(new ScoreDatum(0.0f, e.getKey().toString(), 
            e.getValue().toString(), depth));
      }
    }
            

           四.eclipse运行源码问题

           运行Crawler的main方法时候会报错. GeneratorReducer第100行, 代码如下:
           batchId = newUtf8(conf.get(GeneratorJob.BATCH_ID));
           这里的conf.get(GeneratorJob.BATCH_ID)为空报错.

           解决方法,修改GeneratorJob中的public Map run(Map args) 方法。添加以下代码

    // generate batchId 
       int randomSeed = Math.abs(new Random().nextInt()); 
       String batchId = (curTime / 1000) + "-" + randomSeed; 
       getConf().set(BATCH_ID, batchId); 
           同样的,SolrIndexerJob的第40行,String batchId = (String)args.get(Nutch.ARG_BATCH);因为也为空值而报错,这里

           可以给batchId指定一个值.能达到运行源码正常就行,这时就可以DEBUG详细的查看nutch如何运行了.

 

           五.小结

           Nutch属于Apache的, 支持分布式处理,包含web爬虫和全文搜索功能,看起来美美的.

           不过,用起来蛮复杂的,二次开发不够灵活也略显麻烦,抓取目标不特定,后期有变动的话,要修改的地方会很多.

           如果nutch能满足你80%的需求,如果不考虑后期需求变动会有比较大的修改,看了源码后如果觉得自己可以hold住它,可以使用.

           否则个人建议还是自己开发会简单些.

            

          

                


你可能感兴趣的:(nutch)