`
lovejuan1314
  • 浏览: 341876 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Nutch 研究<三> 将Nutch爬取结果放入Hypertable

阅读更多
想把Nutch抓取的web page结果放入到Hypertable中去,目前思路主要有三个:

1. 修改Nutch源代码,让Nutch基于Hypertable工作,可以参考Hbase的实现. 由于该实现缺失Nutch好多特性,而且不易升级,考虑作罢.

2. 将Nutch抓取结果以命令导出为text的dump文件,然后用MapReduce解析该文件,哪相关信息到Hypertable.

3. 其实和第一一样,只不过是直接使用人家已经改好的基于Hbase的实现,然后导出一份tsv文件导入到Hypertable. 不仅融合了第一的缺点还增加了麻烦. 不考虑.

好,以下代码基于第二种思想实现.

package nutchdump;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.Iterator;

import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.util.Tool;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.hypertable.thrift.ThriftClient;
import org.hypertable.thriftgen.Cell;
import org.hypertable.thriftgen.ClientException;
import org.apache.hadoop.util.ToolRunner;
import org.apache.hadoop.util.Tool;


/**
 * NutchDumpReader
 *
 *Reads the dump entries from nutch dump command output, get each line result to
 *write into hypertable database as special format
 *由于只保存抓取的网页内容,所以只关心Nutch导出的文件中,Content::这一块的相关信息
 *
 * @author(lovejuan1314)
 */

public class NutchDumpReader extends Configured implements Tool{
	
	  // where to put the data in hdfs when we're done
	  private static final String OUTPUT_PATH = "nutch_content_result";

	  // where to read the data from.
	  private static final String INPUT_PATH = "/shared/nutch/segdump";
  
	  static class NutchReaderMapper extends MapReduceBase
      implements Mapper<LongWritable, Text, Text, Text> {
		  
		public NutchReaderMapper() { }  
	
		public void map(LongWritable key, Text value,
				OutputCollector<Text, Text> output, Reporter reporter)
				throws IOException {
			String dumpline = value.toString();
			NutchDumpRecord nutchDumpRecord = new NutchDumpRecord(dumpline);
			String version = nutchDumpRecord.getVersion();
			if (version != null){
				output.collect(new Text("version"), new Text(version));
			}
			String base = nutchDumpRecord.getBase();
			if (base != null){
				output.collect(new Text("base"), new Text(base));
			}
			String ContentType = nutchDumpRecord.getContentType();
			if (ContentType != null){
				output.collect(new Text("ContentType"), new Text(ContentType));
			}
			String metadata = nutchDumpRecord.getMetadata();
			if (metadata != null){
				output.collect(new Text("metadata"), new Text(metadata));
			}
			String url = nutchDumpRecord.getUrl();
			if (url != null){
				output.collect(new Text("url"), new Text(url));
			} 
			
			String content = nutchDumpRecord.getContent();
			if (content != null){
				output.collect(new Text("content"), new Text(content));
			}
			
		}
		  
	  }
	  
	  static class NutchReaderReducer extends MapReduceBase
      implements Reducer<Text, Text, Text, NullWritable> {
		  
		public void reduce(Text key, Iterator<Text> values,
				OutputCollector<Text, NullWritable> output, Reporter reporter)
				throws IOException {
			String valKey = key.toString();
			
			while(values.hasNext()){
				Text val = values.next();
				if (val.toString() != null){
					//write into hypertable
					writeIntoTable(valKey,val.toString());
					// output
					output.collect(key, NullWritable.get());
				}
			}
			
		}
		  
	  }
	  
	  /**
	   * 
	   * @param colName
	   * @param colValue
	   */
	  
	  private static void writeIntoTable(String colName,String colValue){
		  
		  try {
			  
			ThriftClient client = ThriftClient.create("192.168.0.40", 38080);
			// mutator examples
		    long mutator = client.open_mutator("webDb", 0, 0);
		      
		    Timestamp ts = new Timestamp(System.currentTimeMillis());
		      
		      try {
		        Cell cell = new Cell();
		        String sysDt = ts.toString();
//设置行关键字 我使用了系统时间+反转URL的格式
		        cell.row_key = sysDt+" "+"com.mytest.www";
//列名
		        cell.column_family = colName;
//列值
		        cell.value = colValue.getBytes();
		        client.set_cell(mutator, cell);
		      }
		      finally {
		        client.close_mutator(mutator, true);
		      }
			
		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (TException e) {
			e.printStackTrace();
		}catch (ClientException ex){
			ex.printStackTrace();
		}
		  
	  }
	  
	  /** Driver for the actual MapReduce process */
	  
	  private void runJob() throws IOException{
		  JobConf conf = new JobConf(getConf(),NutchDumpReader.class);
		  
		  FileInputFormat.addInputPath(conf, new Path(INPUT_PATH));
		  FileOutputFormat.setOutputPath(conf, new Path(OUTPUT_PATH));
		  
		  conf.setMapperClass(NutchReaderMapper.class);
		  conf.setReducerClass(NutchReaderReducer.class);
		  
		  conf.setOutputKeyClass(Text.class);
		  conf.setOutputValueClass(NullWritable.class);
		  
		  conf.setMapOutputValueClass(Text.class);
		  
		  JobClient.runJob(conf);
	  }


	public int run(String[] arg0) throws Exception {
		runJob();
		return 0;
	}
	
	 public static void main(String [] args) throws Exception {
		    int ret = ToolRunner.run(new NutchDumpReader(), args);
		    System.exit(ret);
		  }

}





package nutchdump;


public class NutchDumpRecord {
	
	// the actual line from dump file
	private String record;
	
	// the fileds on the line
	private String version;
	private String url;
	private String base;
	private String ContentType;
	private String metadata;
	private String content;

	
	//public NutchDumpFileRecord
	
	public NutchDumpRecord(final String record){
		if (record == null){
			this.record = "";
		}else{
			this.record = record;
		}
		this.parse();
	}
	
	protected void parse(){
		int versionIdx = this.record.indexOf("Version:");
		int urlIdx = this.record.indexOf("url:");
		int baseIdx = this.record.indexOf("base:");
		int contentTypeIdx = this.record.indexOf("contentType:");
		int metadataIdx = this.record.indexOf("metadata");
		int contentIdx = this.record.indexOf("Content:");
		
		if (versionIdx != -1){
			this.version = this.record.substring(versionIdx).trim();
		}
		
		if (urlIdx != -1){
			this.url = this.record.substring(urlIdx).trim();
		}
		if (baseIdx != -1){
			this.base = this.record.substring(baseIdx).trim();
		}
		if (contentTypeIdx != -1){
			this.ContentType = this.record.substring(contentTypeIdx).trim();
		}
		if (metadataIdx != -1){
			this.metadata = this.record.substring(metadataIdx).trim();
		}
		if (contentIdx != -1){
			this.content = this.record.substring(contentIdx).trim();
		}
		
	}
	
	// getters

	  /** Return the record */
	public String getRecord(){
		return this.record;
	}
	
	public String getVersion(){
		return this.version;
	}
	public String getUrl(){
		return this.url;
	}
	public String getBase(){
		return this.base;
	}
	public String getContentType(){
		return this.ContentType;
	}
	public String getMetadata(){
		return this.metadata;
	}
	public String getContent(){
		return this.content;
	}
}





//这个类是Hypertable源码中提供的. 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Copyright (C) 2008  Luke Lu (Zvents, Inc.)
 *
 * This file is distributed under the Apache Software License
 * (http://www.apache.org/licenses/)
 */

package nutchdump;

import org.hypertable.thriftgen.*;

import org.apache.thrift.TException;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;

public class ThriftClient extends HqlService.Client {
  public ThriftClient(TProtocol protocol) { super(protocol); }

  // Java only allow super as the first statement of constructor.  It doesn't
  // support multiple inheritance to use the base-from-member idiom either. So,
  // we're resorting to a static factory method here.
  public static ThriftClient
  create(String host, int port, int timeout_ms, boolean do_open)
      throws TTransportException, TException {
    TFramedTransport transport = new TFramedTransport(
        new TSocket(host, port, timeout_ms));
    ThriftClient client = new ThriftClient(new TBinaryProtocol(transport));
    client.transport = transport;

    if (do_open)
      client.open();

    return client;
  }

  // Java doesn't support default argument values, which makes things
  // unnecessarily verbose here
  public static ThriftClient create(String host, int port)
      throws TTransportException, TException {
    return create(host, port, 30000, true);
  }

  public void open() throws TTransportException, TException {
    transport.open();
    do_close = true;
  }

  public void close() {
    if (do_close) {
      transport.close();
      do_close = false;
    }
  }

  private TFramedTransport transport;
  private boolean do_close = false;
}




代码完成后直接打成jar包,在hadoop环境下运行就可以了.


Ps:仅供参考,如果大家有什么更好的方法,欢迎讨论. 另外代码里也没有严格控制数据的一致性,若要在产品上运行还得进一步修改.
分享到:
评论
1 楼 diddyrock 2009-09-24  
其实第一条路最快

相关推荐

    nutch2.3.1安装文档教程

    &lt;value&gt;http://localhost:8983/solr/nutch&lt;/value&gt; &lt;/property&gt; ``` - 上述配置指定了存储类型、HTTP 代理设置、插件包含列表等关键参数。 通过以上步骤,您可以在 CentOS 6.3 系统上成功搭建 Nutch 2.3.1 环境...

    Nutch模块命令

    `bin/nutch readdb &lt;crawldb&gt; (-stats | -dump &lt;out_dir&gt; | -url &lt;url&gt;)` - `&lt;crawldb&gt;`: Crawl 数据库的路径。 - `[-stats]`: 输出数据库的统计信息。 - `[-dump &lt;out_dir&gt;]`: 将数据库信息导出到指定目录。 -...

    nutch_1.4配置

    4. **执行爬行命令**:使用`bin/nutch crawl urls -dir &lt;output_dir&gt; -depth &lt;depth&gt; -topN &lt;num&gt;`命令启动爬虫,其中`&lt;output_dir&gt;`指定爬行结果的存储目录,`&lt;depth&gt;`设定爬行深度,`&lt;num&gt;`控制每层深度的最大爬行...

    nutch的安装方法,好用

    - 打开 `nutch\conf\nutch-site.xml` 文件,在 `&lt;configuration&gt;` 标签内添加以下内容来配置目标站点: ```xml &lt;property&gt; &lt;name&gt;http.robots.agents&lt;/name&gt; &lt;value&gt;http://133.40.188.130:8880/klms&lt;/value&gt; ...

    Nutch搜索引擎·Nutch简单应用(第3期)

    - [-dir&lt;d&gt;]:工作目录参数,用于指定Nutch保存爬取记录的路径,默认路径为当前日期的相对路径。 - [-threads&lt;n&gt;]:参数用于设定Fetcher线程数,覆盖默认配置文件中的fetcher.threads.fetch值,默认为10。 - [-depth...

    nutch10配置(解决代理问题)

    本文将详细介绍如何在Nutch 10版本中配置代理,并解决在配置过程中可能遇到的问题。 #### 配置文件说明 Nutch 10配置文件主要分为几个部分: 1. **Crawling Configuration**:爬虫配置文件,包括`conf/crawl-...

    nutch学习笔记之第一天初学

    &lt;value&gt;c:/nutch-1.0/crawled&lt;/value&gt; &lt;/property&gt; &lt;/nutch-conf&gt; ``` **6. XSLT样式表** Nutch还支持使用XSLT进行数据转换。例如,在XML文件中引用XSL样式表: ```xml &lt;?xml-stylesheet type="text/xsl" href=...

    myeclipse8.5导入nutch1.2源码

    - `&lt;property&gt;&lt;name&gt;searcher.dir&lt;/name&gt;&lt;value&gt;e:/crawl_data&lt;/value&gt;&lt;/property&gt;` 3. **执行爬虫任务**: - 右键点击 `src/java/org.apache.nutch.crawl.Crawl` 类,选择 “Run As” -&gt; “Run Configuration”...

    nutch2.2.1和Mysql 环境的搭建。。。。可以爬下url.但是不知道为什么还有很多空的值在数据库中,还有待.zip

    &lt;value&gt;jdbc:mysql://localhost/nutch?user=root&password=your_password&lt;/value&gt; &lt;/property&gt; &lt;property&gt; &lt;name&gt;storage.data.db.driver&lt;/name&gt; &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt; &lt;/property&gt; ...

    nutch无法下载中文文件的问题

    Nutch 是一个开源的 Web 搜索引擎框架,它主要用于爬取和索引互联网上的网页。在处理中文内容时,可能会遇到一些特定的问题,比如“nutch无法下载中文文件”。这个问题通常与字符编码、URL 处理和配置设置有关。下面...

    Nutch安装配置

    【Nutch安装配置】是关于开源搜索引擎项目Nutch的详细操作流程,主要涉及源码编译、环境搭建和系统配置等内容。Nutch是一款基于Java的搜索引擎框架...理解并熟练掌握这些步骤,将有助于顺利地搭建和运行Nutch搜索引擎。

    Nutch在Tomcat下的部署.doc

    尤其是针对你的抓取目录,将`&lt;nutch-conf&gt;`标签内的内容替换为: ``` &lt;nutch-conf&gt; &lt;property&gt; &lt;name&gt;searcher.dir&lt;/name&gt; &lt;value&gt;Your_crawl_dir_path&lt;/value&gt; &lt;/property&gt; &lt;/nutch-conf&gt; ``` 其中`Your_...

    nutch-访问wap网站

    4. **编译与安装**:编译插件并将其放入Nutch的类路径中,以便在爬虫运行时使用。 四、Nutch配置 在Nutch的配置文件中,我们可以设置`http.agent.name`来定义爬虫的User-Agent字符串,这对于识别为移动设备至关...

    nutch网页爬取总结

    **Nutch 网页爬取总结** **前言** Nutch 是一个开源的网络爬虫项目,由 Apache 基金会维护,主要用于构建大规模的搜索引擎。它提供了从互联网抓取网页、分析链接关系、生成倒排索引等一系列功能。Nutch 的设计目标...

    Nutch 解析器parse部分代码笔记

    &lt;meta name="description" content="This is an example page for Nutch parser." /&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Welcome to Example Page&lt;/h1&gt; &lt;p&gt;This is some text on the page.&lt;/p&gt; &lt;a href=...

    windows下nutch的安装.pdf

    以上命令会执行三个深度级别的抓取,并将结果输出到日志文件中。 Nutch会生成一系列的文件夹和文件来存储索引和相关数据,例如: - crawl:包含爬虫生成的数据; - segments:包含分段的索引数据; - crawl_db:...

    Windows系统下Nutch检索工具的搭建步骤

    - 打开`nutch/conf/nutch-site.xml`文件,在`&lt;configuration&gt;`标签内添加以下内容: ```xml &lt;property&gt; &lt;name&gt;http.agent.name&lt;/name&gt; &lt;value&gt;CustomAgentName&lt;/value&gt; &lt;description&gt;...

    Hadoop-2.4.0+Hbase-0.94.18+Nutch-2.3集群爬虫配置攻略

    2. 指定HBase使用的Hadoop配置目录:`&lt;property&gt;&lt;name&gt;hbase.rootdir&lt;/name&gt;&lt;value&gt;hdfs://localhost:9000/hbase&lt;/value&gt;&lt;/property&gt;` 3. 配置Zookeeper地址:`&lt;property&gt;&lt;name&gt;hbase.zookeeper.quorum&lt;/name&gt;&lt;value...

Global site tag (gtag.js) - Google Analytics