由nutch readseg -dump 中文编码乱码想到的……

两周前,我参考Hadoop权威指南2,写了一个读取SequenceFile的类,想读取Nutch抓取下来的segments文件。当时如果Nutch抓取的是utf8编码的中文页面就可以正常读取,但如果网页是中文编码的话就会出现乱码,比如我抓取了www.163.com,用

bin/nutch crawl urls/ -dir crawl/www.163.com/ -depth 3 -topN 50 -thread 5

 由于163是用的gb2312编码的,读取crawl/www.163.com/segments/下面的文件就有乱码。同样可以用readseg一试

 bin/nutch readseg -dump crawl/www.163.com/segments/20120513192613/ crawl/www.163.com/readseg-result1

 查看readseg-result1/dump文件发现Content::中的网页源码信息中的中文是乱码,但观察其上方的ParseData::和ParseText::却不是乱码,于是我看了Nutch的readseg命令的源代码:org.apache.nutch.segment.SegmentReader

找到其map和reduce方法,想进行改造重新实现一个MySegmentReader,在map方法:

public void map(WritableComparable key, Writable value, OutputCollector<Text, NutchWritable> collector,
		Reporter reporter) throws IOException {
	// convert on the fly from old formats with UTF8 keys.
	// UTF8 deprecated and replaced by Text.
	if (key instanceof Text) {
		newKey.set(key.toString());
		key = newKey;
	}
	collector.collect((Text) key, new NutchWritable(value));
}

 和reduce方法:

public void reduce(Text key, Iterator<NutchWritable> values, OutputCollector<Text, Text> output, Reporter reporter)
		throws IOException {
	StringBuffer dump = new StringBuffer();

	dump.append("\nRecno:: ").append(recNo++).append("\n");
	dump.append("URL:: " + key.toString() + "\n");
	while (values.hasNext()) {
		Writable value = values.next().get(); // unwrap
		if (value instanceof CrawlDatum) {
			dump.append("\nCrawlDatum::\n").append(((CrawlDatum) value).toString());
		} else if (value instanceof Content) {
			dump.append("\nContent::\n").append(((Content) value).toString());
		} else if (value instanceof ParseData) {
			dump.append("\nParseData::\n").append(((ParseData) value).toString());
		} else if (value instanceof ParseText) {
			dump.append("\nParseText::\n").append(((ParseText) value).toString());
		} else if (LOG.isWarnEnabled()) {
			LOG.warn("Unrecognized type: " + value.getClass());
		}
	}
	output.collect(key, new Text(dump.toString()));
}

 我尝试了多种转换编码的方式,然后重新执行MySegmentReader,却总是得到同样的结果Content::中的网页源码信息中的中文始终是乱码。

我想为什么不直接用ParseText::中的编码正确的信息呢?

根据reduce中

 else if (value instanceof ParseText) {
	dump.append("\nParseText::\n").append(((ParseText) value).toString());
}

 的提示,我想可以重新写一个解析类的reduce方法,专门用于生成这种纯文本的ParseText的文件,然后交给Mahout的org.apache.mahout.text.SequenceFilesFromDirectory类 去处理。

今天我又用之前写的读取SequenceFile的类来读取了crawl/www.163.com/segments/20120513192613/parse_text/part-00000/data的信息,就是正常的无乱码的文本:

bin/hadoop jar ~/Desktop/SequenceFileReader.jar segments/20120513192613/parse_text/part-00000/data segdata-parse-text

 产生的结果如下:

      [7261*]    http://news.163.com/12/0511/16/8183GF9B0001124J.html    

猜你喜欢

转载自wujay.iteye.com/blog/1526902