nutch-1.8爬虫网页中文乱码的处理

时间:2022-11-20 03:33:32

Nutch1.8在使用默认网页解析插件解析网页文本时,有些网页会出现在乱码问题。

出现乱码的原因分析
parse-html插件在解析网页文本时,会先使用正则表达匹配出网页的编码。源码如下

(文件路径:NUTCH_HOME/src/plugin/parse-html/src/java/org/apache/nutch/parse/html/HtmlParser.java):

private static Pattern metaPattern =
Pattern.compile("<meta\\s+([^>]*http-equiv=(\"|')?content-type(\"|')?[^>]*)>",
Pattern.CASE_INSENSITIVE);

private static Pattern charsetPattern =
Pattern.compile("charset=\\s*([a-z][_\\-0-9a-z]*)", Pattern.CASE_INSENSITIVE);

该正则表达式只能匹配出使用<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />标明网页编码的网页。国内有些网站是使用<meta charset="utf-8" />来标明网页编码,因此插件无法解析出网页的编程。当无法解析出网页编码时,插件会使用nutch配置文件设置的默认解析编码。如果没有在nutch-site.xml文件中配置默认解析网页的编码,程序会使用nutch-default.xml文件的默认配置。默认配置如下:

(文件路径:NUTCH_HOME/conf/nutch-default.xml)

<property>
<name>parser.character.encoding.default</name>
<value>windows-1252</value>
<description>The character encoding to fall back to when no other information is available</description>
</property>


默认编码是windows-1252,针对没有提取出网页编码的网页,解析出来的网页内容就是乱码了。

解决方法:
1、 在原来匹配基础上增加正则匹配规则,匹配使用<meta charset="utf-8" />标明网页编码的网站,正则表达式是:

private static Pattern metaPatternOther = 

Pattern.compile("<meta\\s+([^>]*charset=\\s*(\"|')?\\s*([a-z][_\\-0-9a-z]*)(\"|')?[^
>]*)>",
Pattern.CASE_INSENSITIVE);
private static Pattern charsetPatternOther =   Pattern.compile("charset=\\s*((\"|')?([a-z][_\\-0-9a-z]*)(\"|')?)",                 Pattern.CASE_INSENSITIVE);
private static Pattern charsetPatternAnother =    Pattern.compile("charset\\s*=\\s*((\"|')?([a-z][_\\-0-9a-z]*)(\"|')?)",                Pattern.CASE_INSENSITIVE);


2、 修改nutch-site.xml配置文件,设置默认解析网页的编码为utf-8或者gb2312,我这里设置的是ut8-8。Nutch会使用配置的默认编码解析网页,对于中文网站来说,主要是这两种编码。

<property>
<name>parser.character.encoding.default</name>
<value>utf-8</value>
<description>The character encoding to fall back to when no other information is available</description>
</property>


经过这样处理,解析爬取的网页大部分乱码被解决掉了。我使用nutch版本是1.8,其它版本不知道也是如此否,可以自行测试。

 

余留问题

还有一些乱码没解决,经过分析,都是繁体字的乱码,而且当转为utf-8时,报错信息是utf-8的编码长度不够。Big5是繁体中文de facto标准,所以这个错误的大概意思就是说utf-8编码一个汉字的字节要比Big5小。由于我们解析网页编码格式时只会分析网页源代码中的“charset”属性的值作为网页编码格式,Big5貌似不作为这个属性值出现(反正我暂时还没见过这种情况),这样繁体就解析不出来了,就成乱码了。(关于这个问题我暂时是这么理解的,慢慢研究吧~~~,欢迎交流探讨!)

 

附录

Big5:这是繁体中文 de facto 标准。
CNS11643:*的官方标准繁体中文编码。
Cp937:繁体中文加上 6204 个使用者自定的字符
Cp948:繁体中文版 IBM OS/2 用的编码方式。
Cp964:繁体中文版 IBM AIX 用的编码方式。
EUC_TW:*的加强版 Unicode。
ISO2022CN:编码中文的一套标准。
ISO2022CN_CNS:编码中文的一套标准,繁体版,袭自 CNS11643。
MS950 或 Cp950:ASCII + Big5,用于*和香港的繁体中文 MS Windows操作系统。
Unicode:有次序记号的 Unicode。次序记号占用两个 byte,如果其值是0xFEFF,表示使用 big-endian(由大到小)的次序为 Unicode 编码;如果其值是 0xFFFF,表示使用 little-endian(由小到大)的次序为 Unicode 编码。
UnicodeBig:使用 big-endian(由大到小)的次序为 Unicode 编码。
UnicodeLittle:使用 little-endian(由小到大)的次序为 Unicode 编码。
UTF8:使用 UTF-8 为 Unicode 编码。