爬虫往往会遇到乱码问题。最简单的方法是根据http的响应信息来获取编码信息。但如果对方网站的响应信息不包含编码信息或编码信息错误,那么爬虫取下来的信息就很可能是乱码。

好的解决办法是直接根据页面内容来自动判断页面的编码。如Mozilla公司的firefox使用的universalchardet编码自动检测工具。

juniversalchardet是universalchardet的Java版本。源码开源于 https://github.com/thkoch2001/juniversalchardet

自动编码主要是根据统计学的方法来判断。具体原理,可以看http://www-archive.mozilla.org/projects/intl/UniversalCharsetDetection.html

现在以Java爬虫常用的httpclient来讲解如何使用。看以下关键代码:

  1. myStream.read(tmp)) 读取httpclient得到的流。我们要做的就是在读流的同时,运用juniversalchardet来检测编码,如果有符合特征的编码的出现,则最后可通过detector.getDetectedCharset()
  2. 可以得到编码,否则返回null。至此,检测工作结束,通过String的构造方法来进行按一定编码构建字符串。

http://mvnrepository.com/artifact/com.googlecode.juniversalchardet/juniversalchardet/1.0.3

<!-- https://mvnrepository.com/artifact/com.googlecode.juniversalchardet/juniversalchardet -->
<dependency>
<groupId>com.googlecode.juniversalchardet</groupId>
<artifactId>juniversalchardet</artifactId>
<version>1.0.3</version>
</dependency>

  

https://code.google.com/archive/p/juniversalchardet/

Java port of universalchardet

1. What is it?

juniversalchardet is a Java port of 'universalchardet', that is the encoding detector library of Mozilla.

The original code of universalchardet is available athttp://lxr.mozilla.org/seamonkey/source/extensions/universalchardet/

Techniques used by universalchardet are described athttp://www.mozilla.org/projects/intl/UniversalCharsetDetection.html

2. Encodings that can be detected

  • Chinese

    • ISO-2022-CN
    • BIG5
    • EUC-TW
    • GB18030
    • HZ-GB-23121
  • Cyrillic

    • ISO-8859-5
    • KOI8-R
    • WINDOWS-1251
    • MACCYRILLIC
    • IBM866
    • IBM855
  • Greek

    • ISO-8859-7
    • WINDOWS-1253
  • Hebrew

    • ISO-8859-8
    • WINDOWS-1255
  • Japanese

    • ISO-2022-JP
    • SHIFT_JIS
    • EUC-JP
  • Korean

    • ISO-2022-KR
    • EUC-KR
  • Unicode

    • UTF-8
    • UTF-16BE / UTF-16LE
    • UTF-32BE / UTF-32LE / X-ISO-10646-UCS-4-34121 / X-ISO-10646-UCS-4-21431
  • Others

    • WINDOWS-1252

1 Currently not supported by Java

3. How to use it

  1. Construct an instance of org.mozilla.universalchardet.UniversalDetector.
  2. Feed some data (typically several thousands bytes) to the detector by calling UniversalDetector.handleData().
  3. Notify the detector of the end of data by calling UniversalDetector.dataEnd().
  4. Get the detected encoding name by calling UniversalDetector.getDetectedCharset().
  5. Don't forget to call UniversalDetector.reset() before you reuse the detector instance.

Sample Code

Download ``` import org.mozilla.universalchardet.UniversalDetector;

public class TestDetector { public static void main(String[] args) throws java.io.IOException { byte[] buf = new byte[4096]; String fileName = args[0]; java.io.FileInputStream fis = new java.io.FileInputStream(fileName);

// (1)
UniversalDetector detector = new UniversalDetector(null); // (2)
int nread;
while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
// (3)
detector.dataEnd(); // (4)
String encoding = detector.getDetectedCharset();
if (encoding != null) {
System.out.println("Detected encoding = " + encoding);
} else {
System.out.println("No encoding detected.");
} // (5)
detector.reset();

} } ```

4. Related Works

jchardet

  • http://jchardet.sourceforge.net/ jchardet is another Java port of the Mozilla's encoding dectection library. The main difference between jchardet and juniversalchardet is modules they are based on. jchardet is based on the 'chardet' module that has long existed. juniversalchardet is based on the 'universalchardet' module that is new and generally provides better accuracy on detection results.

5. License

The library is subject to the Mozilla Public License Version 1.1. Alternatively, the library may be used under the terms of either the GNU General Public License Version 2 or later, or the GNU Lesser General Public License 2.1 or later.

用juniversalchardet解决爬虫乱码问题的更多相关文章

  1. 22-python爬虫解决gbk乱码问题

    转载自: python爬虫解决gbk乱码问题   今天尝试了下爬虫,爬取一本小说,忘语的凡人修仙仙界篇,当然这样不好,大家要支持正版. 爬取过程中是老套路,先获取网页源代码 # -*- coding: ...

  2. 增加UBUNTU字符集 解决中文乱码问题

    对GBK,GB2312,GB18030字符集的支持是UBUNTU中文乱码的罪魁祸首,其实我们可以在保持UTF-8为默认编码的条件下添加对这几个编码的支持,以解决中文乱码问题. 我想这个问题肯定有其他人 ...

  3. Sublime Text 2—解决中文乱码

    Sublime Text 2是一个非常棒的代码及文本编辑器,绿色小巧.速度飞快,跨平台支持Win/Mac/Linux,支持32与64位,支持各种流行编程语言的语法高亮.代码补全等,有着许多其他编辑器没 ...

  4. zabbix解决中文乱码问题(没有测试成功)

    zabbix解决中文乱码问题 1.在windows系统中找一个自己喜欢的字体,这里我们用:msyh.ttf 2.将字体上传至/var/www/html/zabbix/fonts目录下 [root@za ...

  5. Spring项目解决Post乱码

    Java EE解决Post乱码:在web.xml中加入: <filter> <filter-name>encodingFilter</filter-name> &l ...

  6. 二招解决php乱码问题

    PHP的乱码问题已经说了N+1遍了,但还是经常看到新手不知道该如何解决php乱码问题,在此本人再重新给总结一下,希望对新手有点帮助 php网页出现乱码一般是在建立数据库时用的编码和php网页的编码不同 ...

  7. 利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码

    利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码 2014-07-31 12:53 1047人阅读 评论(0) 收藏  ...

  8. 【原创】通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...

    这篇blog重点在解决问题,如果你对字符编码并不是特别了解,建议先看看 < [原创]通俗易懂地解决中文乱码问题(1) --- 跨平台乱码 >. 当然,如果只是针对解决这个Mysql插入报错 ...

  9. 解决 IntelliJ 乱码问题

    原文:解决 IntelliJ 乱码问题 汉字符在IntelliJ的控制台输出乱码.编译器在编译的时候,把汉字符编译成非UTF-8而引起乱码.我是在做Jsoup解析的时候出现的错误,其实归根结底确实编译 ...

随机推荐

  1. 访问 iframe 内部控件方法

    方法虽然简单,但是经常忘记,网上一查,很多方法兼容性都有问题,这段代码至少兼容IE和Chrome setInterval(function(){ document.getElementById('ma ...

  2. fastdfs(https://www.jianshu.com/p/1c71ae024e5e)

    参考 官方网站:https://github.com/happyfish100/ 配置文档:https://github.com/happyfish100/fastdfs/wiki/ 参考资料:htt ...

  3. tile38 复制配置

    基于复制我们可以保证tile38 server 的ha 环境准备 docker-compose 文件 说明里面多了一个webhook 的服务,可以不用管   version: "3" ...

  4. 学习笔记:Javascript 变量 包装对象

    学习笔记:Javascript 变量 包装对象 如下代码,可以输出字符的长度. var str = "Tony"; str.length; 这时再试试以下代码,返回是 undefi ...

  5. ML(附录1)——梯度下降

    梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以).在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的 ...

  6. create-react-app 搭建的项目中,引入 webpack-bundle-analyzer 打包分析

    安装npm intall webpack-bundle-analyzer --save-dev 在 config/webpack.config.prod.js 文件(推荐)或 config/webpa ...

  7. sql语句实战

    1,排名,自身连接,用count,去重用distinct 2,累加,和上面一样,自身连接,用sum 3,count函数不用group by只有一组

  8. Scala实战

    1. Eclipse中设置scala调试器 scala的调试器要选择Scala Application(new debuger)Launcher:开始选择图省事,选择了一个字母少的,亲切的Launch ...

  9. Java变量的初始值

    Java中的变量如果没有赋值,成员变量默认被初始化,局部变量则不会. 对于成员变量 int a;         // a的初始值为0 如下例中的成员变量a,b,c,d public class Va ...

  10. Linux 高级文本处理命令

    1.2.1 cut命令 cut命令可以从一个文本文件或者文本流中提取文本列. cut语法 [root@www ~]# cut -d'分隔字符' -f fields     ## 用于有特定分隔字符 [ ...