nutch2.0+cassandra中文网页乱码问题

用nutch2.0+cassandra1.0爬取和存储网页时发现gbk编码的网页解析提取文本时中文全都变成乱码,非常奇怪,之前nutch1.x从来就不会出现中文乱码的问题的,因为nutch1.x和nutch2.x用的爬虫代码差不多是一样的,所以我猜可能是保存到cassandra时有问题。看了下它保存网页到cassandra的源码,所有需要保存的值它都转换成二进制封装成ByteBuffer对象传到gora中持久化。看下gora-cassandra的源码中操作cassandra的部分

CassandraClient.java中,addColumn添加数据,值为ByteBuffer的则转换成字符串

  1. public void addColumn(String key, String fieldName, Object value) {  
  2.     if (value == null) {  
      return;      }      if (value instanceof ByteBuffer) {        value = toString((ByteBuffer) value);      }            String columnFamily = this.cassandraMapping.getFamily(fieldName);      String columnName = this.cassandraMapping.getColumn(fieldName);            this.mutator.insert(key, columnFamily, HFactory.createStringColumn(columnName, value.toString()));    }  

ByteUtils.java中把byte转换成字符串的代码

  1. public static String toString(final byte [] b, int off, int len) {  
  2.     if(b == null) {  
  3.       return null;  
  4.     }  
  5.     if(len == 0) {  
  6.       return "";  
  7.     }  
  8.     String result = null;  
  9.     try {  
  10.       result = new String(b, off, len, "UTF-8");  
  11.     } catch (UnsupportedEncodingException e) {  
  12.       e.printStackTrace();  
  13.     }  
  14.     return result;  
  15.   }  

坑爹了,直接就转换成UTF-8保存的,也就是说爬下gbk编码的网页,它把gbk编码转成了UTF-8的字符串,保存到cassandra中,本来这样转换成utf-8也没问题的,不过后来到nutch执行解析的时候,由于nutch的提取页面编码算法比较偏向于请求头的编码(如果请求头没有就提取文件进行计算猜测),而此时的charset=gbk,也就gbk编码。原来utf-8存储到cassandra的数据去出来时转换成了gbk编码,不乱码才怪,知道了原因,要解决就好办了。

我在想为什么它不直接就用二进制的格式存储,这样感觉效率要高点,然后就又看到了CassandraClient.java中的toString方法,还有个TODO注释在那,说不要把二进制的字段从字节转换成字符串存储,原来是还没有完善的。

  1. /** 
  2.    * TODO do no convert bytes to string to store a binary field 
  3.    * @param value 
  4.    * @return 
  5.    */  
  6.   private static String toString(ByteBuffer value) {  
  7.     ByteBuffer byteBuffer = (ByteBuffer) value;  
  8.     return ByteUtils.toString(byteBuffer.array(), 0, byteBuffer.limit());  
  9.   }  

于是就到git上看了下gora0.3版的代码,果然改了,不直接转换成字符串存储了,原来还想自己解决,看来又省了,最简单的解决方法就是把nutch2.0的gora依赖库从0.2,改成0.3

相关推荐