在爬取内容时,遇到乱码问题。故需对网页内容编码格式做判断,方式大体分为三种:一、从header标签中获取Content-Type=#Charset;二、从meta标签中获取Content-Type=#Charset;三、根据页面内容分析编码格式。

其中一/二方式并不能准确指示该页面的具体编码方式,周全考虑,加入第三种方式。

第三种方式引入开源jar包info.monitorenter.cpdetector,可以从github上面下载(https://github.com/onilton/cpdetector-maven-repo/tree/master/info/monitorenter/cpdetector/1.0.10)下载。整个代码如下:

 import info.monitorenter.cpdetector.io.ASCIIDetector;
import info.monitorenter.cpdetector.io.ByteOrderMarkDetector;
import info.monitorenter.cpdetector.io.CodepageDetectorProxy;
import info.monitorenter.cpdetector.io.JChardetFacade;
import info.monitorenter.cpdetector.io.ParsingDetector;
import info.monitorenter.cpdetector.io.UnicodeDetector; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map; import org.apache.commons.io.IOUtils; public class PageEncoding {
/** 测试用例
* @param args
*/
public static void main(String[] args) { String charset = getEncodingByContentStream("http://www.baidu.com"); System.out.println(charset);
} /**
* 从header中获取页面编码
* @param strUrl
* @return
*/
public static String getEncodingByHeader(String strUrl){
String charset = null;
try {
URLConnection urlConn = new URL(strUrl).openConnection();
// 获取链接的header
Map<String, List<String>> headerFields = urlConn.getHeaderFields();
// 判断headers中是否存在Content-Type
if(headerFields.containsKey("Content-Type")){
//拿到header 中的 Content-Type :[text/html; charset=utf-8]
List<String> attrs = headerFields.get("Content-Type");
String[] as = attrs.get(0).split(";");
for (String att : as) {
if(att.contains("charset")){
// System.out.println(att.split("=")[1]);
charset = att.split("=")[1];
}
}
}
return charset;
} catch (MalformedURLException e) {
e.printStackTrace();
return charset;
} catch (IOException e) {
e.printStackTrace();
return charset;
}
} /**
* 从meta中获取页面编码
* @param strUrl
* @return
*/
public static String getEncodingByMeta(String strUrl){
String charset = null;
try {
URLConnection urlConn = new URL(strUrl).openConnection();
//避免被拒绝
urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36");
// 将html读取成行,放入list
List<String> lines = IOUtils.readLines(urlConn.getInputStream());
for (String line : lines) {
if(line.contains("http-equiv") && line.contains("charset")){
// System.out.println(line);
String tmp = line.split(";")[1];
charset = tmp.substring(tmp.indexOf("=")+1, tmp.indexOf("\""));
}else{
continue;
}
}
return charset;
} catch (MalformedURLException e) {
e.printStackTrace();
return charset;
} catch (IOException e) {
e.printStackTrace();
return charset;
}
} /**
* 根据网页内容获取页面编码
* case : 适用于可以直接读取网页的情况(例外情况:一些博客网站禁止不带User-Agent信息的访问请求)
* @param url
* @return
*/
public static String getEncodingByContentUrl(String url) {
CodepageDetectorProxy cdp = CodepageDetectorProxy.getInstance();
cdp.add(JChardetFacade.getInstance());// 依赖jar包 :antlr.jar & chardet.jar
cdp.add(ASCIIDetector.getInstance());
cdp.add(UnicodeDetector.getInstance());
cdp.add(new ParsingDetector(false));
cdp.add(new ByteOrderMarkDetector()); Charset charset = null;
try {
charset = cdp.detectCodepage(new URL(url));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(charset);
return charset == null ? null : charset.name().toLowerCase();
} /**
* 根据网页内容获取页面编码
* case : 适用于不可以直接读取网页的情况,通过将该网页转换为支持mark的输入流,然后解析编码
* @param strUrl
* @return
*/
public static String getEncodingByContentStream(String strUrl) {
Charset charset = null;
try {
URLConnection urlConn = new URL(strUrl).openConnection();
//打开链接,加上User-Agent,避免被拒绝
urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"); //解析页面内容
CodepageDetectorProxy cdp = CodepageDetectorProxy.getInstance();
cdp.add(JChardetFacade.getInstance());// 依赖jar包 :antlr.jar & chardet.jar
cdp.add(ASCIIDetector.getInstance());
cdp.add(UnicodeDetector.getInstance());
cdp.add(new ParsingDetector(false));
cdp.add(new ByteOrderMarkDetector()); InputStream in = urlConn.getInputStream();
ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.toByteArray(in));
// detectCodepage(InputStream in, int length) 只支持可以mark的InputStream
charset = cdp.detectCodepage(bais, 2147483647);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return charset == null ? null : charset.name().toLowerCase();
}
}

注意的点:

1.info.monitorenter.cpdetector未在mvn-repository中开源,因而无法从mvn-repository中下载,需要将该jar下到本地,然后手动导入到本地repository,mvn命令如下:

mvn install:install-file -Dfile=jar包的位置 -DgroupId=该jar的groupId -DartifactId=该jar的artifactId -Dversion=该jar的version -Dpackaging=jar

然后在pom.xml中添加该jar的依赖

<!-- charset detector -->
<dependency>
<groupId>info.monitorenter.cpdetector</groupId>
<artifactId>cpdetector</artifactId>
<version>1.0.10</version>
</dependency>

2.JChardetFacade.getInstance()在引入antlr.jar和chardet.jar之前会报异常,在pom.xml中添加这两个jar的dependency:

<!-- antlr -->
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.7</version>
</dependency>
<!-- ChardetFacade -->
<dependency>
<groupId>net.sourceforge.jchardet</groupId>
<artifactId>jchardet</artifactId>
<version>1.0</version>
</dependency>

如果是普通项目则无需关心pom.xml,直接把这三个jar包下载下来然后添加到该项目的环境中即可

java判断网页的编码格式的更多相关文章

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

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

  2. js判断网页是否加载完毕 包括图片

    <script type="text/javascript" language="JavaScript"> //: 判断网页是否加载完成 docum ...

  3. JS判断网页是否在微信中打开/

    JS判断网页是否在微信中打开,代码如下: <script type="text/javascript"> function is_weixn(){ var ua = n ...

  4. 使用Java判断字符串中的中文字符数量

    Java判断一个字符串str中中文的个数,经过总结,有以下几种方法(全部经过验证),可根据其原理判断在何种情况下使用哪个方法: 1. char[] c = str.toCharArray(); for ...

  5. jQuery判断网页中的id是否有重复的

    From:http://blog.csdn.net/china_skag/article/details/6915323判断网页中的ID是否有重复的:指定ID判断 $(function(){ $(&q ...

  6. Java判断回文数算法简单实现

    好久没写java的代码了, 今天闲来无事写段java的代码,算是为新的一年磨磨刀,开个头,算法是Java判断回文数算法简单实现,基本思想是利用字符串对应位置比较,如果所有可能位置都满足要求,则输入的是 ...

  7. Ifvisible.js – 判断网页中的用户是闲置还是活动状态

    ifvisible.js 是一个跨浏览器.轻量级的方式,用户检查用户在浏览页面或正在与它进行交互.它可以处理活动状态,如在页面上空闲或活跃.您还可以使用 ifvisible.js 智能设置您的间隔,如 ...

  8. C# WebBrowser准确判断网页最终装载完毕

    == 最近写了个软件叫WebAutoScript,目的用于,网页的自动操作处理,就是说,所有你在网页上面的操作,都可以录到一个脚本中,然后可以回放这个操作过程..我是说任何过程. 程序是用C#写的,其 ...

  9. Java 判断操作系统类型(适用于各种操作系统)

    Java 判断操作系统类型(适用于各种操作系统) 最近一段时间写一个授权的程序,需要获取很多信息来保证程序不能随意复制使用,必须经过授权才可以. 为了限制用户使用的操作系统,必须有统一的方法来获取才可 ...

随机推荐

  1. Android数据库之判断表是否存在

    Android开发的时候我们可能会用到它的本地数据库,在使用的时候有可能我们已经储存了数据了,但是,我们的表已经创建了,里面有数据,我们要怎么判断表是否已经创建可能就需要琢磨一下. 以下便是利用了,查 ...

  2. 使用jemeter手工编写注册、登陆脚本 运用 fiddler (一)

    我们要使用jemeter来手工写一个脚本 我们要使用到两个工具 一个 就是  jmeter  一个就是 fiddler 为什么要使用fiddler   ? 因为能够帮我们正确精准的找到我们需要的数据 ...

  3. T4模板生成代码。 数据实体层与数据仓储层。备注

    文件生成模板:TempleteManager.ttinclude <#@ assembly name="System.Core" #><#@ assembly n ...

  4. PHP面向对象编程基本原则

    首先祝大家节日快乐!!! 额,不知道你们剁手没,小梦是没有!整整已经错过了第九个年头! 小伙伴是不是有一种感觉,PHP入门的时候简直爱不释手,总是把 "PHP是世界上最好的语言" ...

  5. flask设置配置文件的四钟方式

    # -*- coding: utf-8 -*- DEBUG = True # -*- coding: utf-8 -*- from flask import Flask,session,current ...

  6. dotnet core webapi +vue 搭建前后端完全分离web架构

    架构 服务端采用 dotnet core  webapi 前端采用: Vue + router +elementUI+axios 问题 使用前后端完全分离的架构,首先遇到的问题肯定是跨域访问.前后端可 ...

  7. 51 Nod 1028 大数乘法 V2【Java大数乱搞】

    1028 大数乘法 V2 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 给出2个大整数A,B,计算A*B的结果. Input 第1行:大数A 第2行:大数B (A ...

  8. HDU6235-Permutation-水题-2017中国大学生程序设计竞赛-哈尔滨站-重现赛

    Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  9. hdu_3068 最长回文(Manacher算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Time Limit: 4000/2000 MS (Java/Others)    M ...

  10. QQ群友在线/离线,如何测试?

    上篇文章『QQ好友在线/离线,如何测试?』针对即时通讯的"状态"进行了分析和总结,主要说到了QQ好友在线/离线实现方案,测试过程中需要注意的测试点. 针对好友状态实时性的要求需要使 ...