原文链接 http://www.cnblogs.com/nanxin/archive/2013/03/27/2984320.html

前言

  最近做一个搜索项目,需要爬取很多网站获取需要的信息。在爬取网页的时候,需要获得该网页的编码,不然的话会发现爬取下来的网页有很多都是乱码。

分析

  一般情况下,网页头信息会指定编码,可以解析header或者meta获得charset。但有时网页并没没有指定编码,这时就需要通过网页内容检测编码格式,通过调研,最好用的还是cpdetector。 

  cpdetector自动检测文本编码格式,谁先返回非空,就以该结果为字符编码。内置了一些常用的探测实现类,这些探测实现类的实例可以通过add方法加进来,如等,detector按照“谁先返回非空的探测结果,就以谁的结果为准”的原则返回探测到的字符集编码。

1、首先,可从header中解析charset

  网页头信息中的Content-Type会指定编码,如图:

  

  可以通过分析header,查找字符编码。

Map<String, List<String>> map = urlConnection.getHeaderFields();
Set<String> keys = map.keySet();
Iterator<String> iterator = keys.iterator(); // 遍历,查找字符编码
String key = null;
String tmp = null;
while (iterator.hasNext()) {
key = iterator.next();
tmp = map.get(key).toString().toLowerCase();
// 获取content-type charset
if (key != null && key.equals("Content-Type")) {
int m = tmp.indexOf("charset=");
if (m != -1) {
strencoding = tmp.substring(m + 8).replace("]", "");
return strencoding;
}
}
}

2、其次,可从网页meta中解析出charset

  正常情况下,在写网页时,会指定网页编码,可在meta中读出来。如图:

  

  首先获取网页流,因为英文和数字不会乱码,可以解析meta,获得charset。

StringBuffer sb = new StringBuffer();
String line;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(url
.openStream()));
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
} catch (Exception e) { // Report any errors that arise
System.err.println(e);
System.err
.println("Usage: java HttpClient <URL> [<filename>]");
}
String htmlcode = sb.toString();
// 解析html源码,取出<meta />区域,并取出charset
String strbegin = "<meta";
String strend = ">";
String strtmp;
int begin = htmlcode.indexOf(strbegin);
int end = -1;
int inttmp;
while (begin > -1) {
end = htmlcode.substring(begin).indexOf(strend);
if (begin > -1 && end > -1) {
strtmp = htmlcode.substring(begin, begin + end).toLowerCase();
inttmp = strtmp.indexOf("charset");
if (inttmp > -1) {
strencoding = strtmp.substring(inttmp + 7, end).replace(
"=", "").replace("/", "").replace("\"", "")
.replace("\'", "").replace(" ", "");
return strencoding;
}
}
htmlcode = htmlcode.substring(begin);
begin = htmlcode.indexOf(strbegin);
}

3、当使用1、2解析不出编码时,使用cpdetector根据网页内容探测出编码格式

  可以添加多个编码探测实例:

public static void getFileEncoding(URL url) throws MalformedURLException, IOException {
CodepageDetectorProxy codepageDetectorProxy = CodepageDetectorProxy.getInstance(); codepageDetectorProxy.add(JChardetFacade.getInstance());
codepageDetectorProxy.add(ASCIIDetector.getInstance());
codepageDetectorProxy.add(UnicodeDetector.getInstance());
codepageDetectorProxy.add(new ParsingDetector(false));
codepageDetectorProxy.add(new ByteOrderMarkDetector()); Charset charset = codepageDetectorProxy.detectCodepage(url);
System.out.println(charset.name());
}
}

spider JAVA如何判断网页编码 (转载)的更多相关文章

  1. 使用chardet模块判断网页编码

    import chardet import urllib.request url='http://stock.sohu.com/news/' html = urllib.request.urlopen ...

  2. C#判断文件编码——常用字法

    使用中文写文章,当篇幅超过一定程度,必然会使用到诸如:“的”.“你”.“我”这样的常用字.本类思想便是提取中文最常用的一百个字,使用中文世界常用编码(主要有GBK.GB2312.GB18030.UTF ...

  3. Java应用中的编码问题(转载)

    第三篇:JAVA字符编码系列三:Java应用中的编码问题这部分采用重用机制,引用一篇文章来完整本部分目标.来源:  Eceel东西在线 问题研究--字符集编码 地址:http://china.ecee ...

  4. Java进阶(三十) 判断字符串编码类型

    java 判断字符串编码类型 public static String getEncoding(String str) { String encode = "GB2312"; tr ...

  5. 【转载】python抓取网页时候,判断网页编码格式

    在web开发的时候我们经常会遇到网页抓取和分析,各种语言都可以完成这个功能.我喜欢用python实现,因为python提供了很多成熟的模块,可以很方便的实现网页抓取.但是在抓取过程中会遇到编码的问题, ...

  6. (转载)java中判断字符串是否为数字的方法的几种方法

    java中判断字符串是否为数字的方法: 1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < ...

  7. Java 序列化 序列化与单例模式 [ 转载 ]

    Java 序列化 序列化与单例模式 [ 转载 ] @author Hollis 本文将通过实例+阅读Java源码的方式介绍序列化是如何破坏单例模式的,以及如何避免序列化对单例的破坏. 单例模式,是设计 ...

  8. 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  9. java中的字符编码方式

    1. 问题由来 面试的时候被问到了各种编码方式的区别,结果一脸懵逼,这个地方集中学习一下. 2. 几种字符编码的方式 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符 ...

随机推荐

  1. c语言_头文件_stdlib

    简介 stdlib 头文件即standard library标准库头文件 stdlib 头文件里包含了C.C++语言的最常用的系统函数 该文件包含了C语言标准库函数的定义 stdlib.h里面定义了五 ...

  2. VC常用数据类型使用转换详解

    一.其它数据类型转换为字符串 短整型(int)itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制itoa(i,temp,2); ///按二进制方式转换 长整型 ...

  3. url操作一网打尽(一)

    1:url实际应用简介 近期研究发现通过url传递参数很普遍的(淘宝也是这样做的), 通过修改url来传递参数,比如通过关键字搜索某件商品的时候,链接便追加了相应参数.在请求接口的时候直接对url进行 ...

  4. Codeforces Round #364 (Div. 2) E. Connecting Universities

    E. Connecting Universities time limit per test 3 seconds memory limit per test 256 megabytes input s ...

  5. hdu_1495_非常可乐(bfs模拟)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1495 题意:不解释 题解:BFS模拟,不过要细心,把所有情况都列举出来,开一个数组记录状态,代码有点长 ...

  6. servlet第3讲(中集)----同一用户的不同页面共享数据

    5.session 5.1session概述 5.2.session应用举例  

  7. .NET面试题目一

    简单介绍下ADO.NET和ADO主要有什么改进? 答:ADO以Recordset存储,而ADO.NET则以DataSet表示,ADO.NET提供了数据集和数据适配器,有利于实现分布式处理,降低了对数据 ...

  8. CentOS6.6 部署Apache+Svn

    svn代码 目前大多数公司 管理代码都是用这个 这个比较方便简单,git用的人数也比较多,我们下面来部署一下这个程序 svn+apache集成 系统环境 # cat /etc/redhat-relea ...

  9. MyEclipse build path no actions available

    MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java.Java EE以及移动应用的开发.MyEclipse的功能非常强大,支持也十分广泛 ...

  10. runtime——消息机制

    本文授权转载,作者:Sindri的小巢(简书) 从异常说起 我们都知道,在iOS中存在这么一个通用类类型id,它可以用来表示任何对象的类型 —— 这意味着我们使用id类型的对象调用任何一个方法,编译器 ...