在爬取内容时,遇到乱码问题。故需对网页内容编码格式做判断,方式大体分为三种:一、从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. 【转载】MySQL之权限管理

    一.MySQL权限简介 关于mysql的权限简单的理解就是mysql允许你做你全力以内的事情,不可以越界.比如只允许你执行select操作,那么你就不能执行update操作.只允许你从某台机器上连接m ...

  2. [转载]解决sudo: sorry, you must have a tty to run sudo

    前几天遇到一个问题,在一个终端中调用另一个shell,始终是无法执行的,后来捕捉到报错信息为sudo: sorry, you must have a tty to run sudo,后来,在网上了解到 ...

  3. 移动端web总结

    viewport 通用模版: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  4. ABP Zero示例项目问题总结

    1.ABP Zero项目,登录时出现如图“Empty or invalid anti forgery header token.”错误提示 ABP Zero项目,登录时出现如图“Empty or in ...

  5. AOP---jdk动态代理的思考

    引出问题:动态代理中是谁调用了invoke方法 为了更好的说明情况,我先写一个动态代理类 a.Person类 public interface Person { public void eating( ...

  6. Elastic Stack之kibana入门

    为了解决公司的项目在集群环境下查找日志不便的问题,我在做过简单调研后,选用Elastic公司的Elastic Stack产品作为我们的日志收集,存储,分析工具. Elastic Stack是ELK(E ...

  7. bzoj:1776: [Usaco2010 Hol]cowpol 奶牛政坛

    Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片 ...

  8. [51nod1197]字符串的数量 V2

    用N个不同的字符(编号1 - N),组成一个字符串,有如下要求: (1) 对于编号为i的字符,如果2 * i > n,则该字符可以作为结尾字符.如果不作为结尾字符而是中间的字符,则该字符后面可以 ...

  9. [51nod1232]完美数

    如果一个数能够被组成它的各个非0数字整除,则称它是完美数.例如:1-9都是完美数,10,11,12,101都是完美数,但是13就不是完美数(因为13不能被数字3整除). 现在给定正整数x,y,求x和y ...

  10. [bzoj1700]: [Usaco2007 Jan]Problem Solving 解题

    不能贪心!不能贪心!不能贪心! 反正有反例(有的题目月初支付款很少,月末支付款很大,和前面的题凑到一个月的话可能导致下个月写不了= =这时放后一个月,和后面的题一起开始写可能更优) 比如: 50 44 ...