在爬取内容时,遇到乱码问题。故需对网页内容编码格式做判断,方式大体分为三种:一、从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. Redis 部署主从哨兵 C#使用,实现自动获取redis缓存 实例1

    源码示例下载链接: https://pan.baidu.com/s/1eTA63T4 密码: un96 实现目标:windows 下安装 一台master服务 一台salve redis服务器 并且哨 ...

  2. Python pandas ERROR 2006 (HY000): MySQL server has gone away

    之前在做python pandas大数据分析的时候,在将分析后的数据存入mysql的时候报ERROR 2006 (HY000): MySQL server has gone away 原因分析:在对百 ...

  3. True 和 False

    True 和 False是Python中的关键字. 'True' 和 'False'是Python中的字符串. true 和 false 是Python中的变量名,需要提前定义.

  4. ssm工程集成mybatis分页插件pagehelper

    1    首先需要在mybatis的配置文件SqlMapConfig.xml文件中配置pagehelper插件 <plugins> <plugin interceptor=" ...

  5. springMvc项目的搭建,暂时没有整合持久层框架(java Config配置对比xml配置)

    public class WebInit implements WebApplicationInitializer { @Override public void onStartup(ServletC ...

  6. 用Token令牌维护微服务之间的通信安全的实现

    在微服务架构中,如果忽略服务的安全性,任由接口暴露在网络中,一旦遭受攻击后果是不可想象的. 保护微服务键安全的常见方案有:1.JWT令牌(token) 2.双向SSL 3.OAuth 2.0 等 本文 ...

  7. mysql数据库表结构与表约束

    表结构操作: 添加单列:alter table tb_name add [column] col_name 添加一列: alter table `sudty` add `aaa` int; 添加多列: ...

  8. Flask框架

    FLask框架的简单介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请 ...

  9. Linux批量处理文件脚本

    Linux shell字符串截取与拼接 一 Linux 的字符串截取很有用.有八种方法. 假设有变量 var=http://www.linuxidc.com/123.htm 1  # 号截取,删除左边 ...

  10. bzoj:1681 [Usaco2005 Mar]Checking an Alibi 不在场的证明

    Description A crime has been comitted: a load of grain has been taken from the barn by one of FJ's c ...