java判断网页的编码格式
在爬取内容时,遇到乱码问题。故需对网页内容编码格式做判断,方式大体分为三种:一、从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判断网页的编码格式的更多相关文章
- 【转载】python抓取网页时候,判断网页编码格式
在web开发的时候我们经常会遇到网页抓取和分析,各种语言都可以完成这个功能.我喜欢用python实现,因为python提供了很多成熟的模块,可以很方便的实现网页抓取.但是在抓取过程中会遇到编码的问题, ...
- js判断网页是否加载完毕 包括图片
<script type="text/javascript" language="JavaScript"> //: 判断网页是否加载完成 docum ...
- JS判断网页是否在微信中打开/
JS判断网页是否在微信中打开,代码如下: <script type="text/javascript"> function is_weixn(){ var ua = n ...
- 使用Java判断字符串中的中文字符数量
Java判断一个字符串str中中文的个数,经过总结,有以下几种方法(全部经过验证),可根据其原理判断在何种情况下使用哪个方法: 1. char[] c = str.toCharArray(); for ...
- jQuery判断网页中的id是否有重复的
From:http://blog.csdn.net/china_skag/article/details/6915323判断网页中的ID是否有重复的:指定ID判断 $(function(){ $(&q ...
- Java判断回文数算法简单实现
好久没写java的代码了, 今天闲来无事写段java的代码,算是为新的一年磨磨刀,开个头,算法是Java判断回文数算法简单实现,基本思想是利用字符串对应位置比较,如果所有可能位置都满足要求,则输入的是 ...
- Ifvisible.js – 判断网页中的用户是闲置还是活动状态
ifvisible.js 是一个跨浏览器.轻量级的方式,用户检查用户在浏览页面或正在与它进行交互.它可以处理活动状态,如在页面上空闲或活跃.您还可以使用 ifvisible.js 智能设置您的间隔,如 ...
- C# WebBrowser准确判断网页最终装载完毕
== 最近写了个软件叫WebAutoScript,目的用于,网页的自动操作处理,就是说,所有你在网页上面的操作,都可以录到一个脚本中,然后可以回放这个操作过程..我是说任何过程. 程序是用C#写的,其 ...
- Java 判断操作系统类型(适用于各种操作系统)
Java 判断操作系统类型(适用于各种操作系统) 最近一段时间写一个授权的程序,需要获取很多信息来保证程序不能随意复制使用,必须经过授权才可以. 为了限制用户使用的操作系统,必须有统一的方法来获取才可 ...
随机推荐
- 使用xUnit为.net core程序进行单元测试(上)
一. 导读 为什么要编写自动化测试程序(Automated Tests)? 可以频繁的进行测试 可以在任何时间进行测试,也可以按计划定时进行,例如:可以在半夜进行自动测试. 肯定比人工测试要快. 可以 ...
- Node.js学习笔记(三): 事件机制
大部分的nodejs核心api都建立在异步的事件驱动架构之上,所以events是Node.js 最重要的模块,它提供了唯一的接口.events 模块不仅用于用户代码与 Node.js 下层事件循环的交 ...
- Django--进阶--中间件的使用
- 中间件是什么? 中间件是一个钩子框架,它们可以介入Django 的请求和响应处理过程.它是一个轻量级.底层的“插件”系统,用于在全局修改Django 的输入或输出. 每个中间件组件负责完成某个特定 ...
- 【eclipse】Target runtime Apache Tomcat v7.0 is not defined解决
在eclipse中导入项目时提示Target runtime Apache Tomcat v7.0 is not defined, 解决方法:右键项目--properties--targeted ru ...
- Java中组合 设计技巧 实例
关于组合 和 集成 先放两篇文章:这两篇文章写的太好了. http://blog.csdn.net/u013905744/article/details/51752044 Java的组合(持有对 ...
- Mac效率:配置Alfred web search
// 这是一篇导入进来的旧博客,可能有时效性问题. 想用搜索引擎搜东西,或者查字典时,一般的workflow是:打开浏览器-->打开搜索引擎/字典网站-->输入搜索关键字-->回车. ...
- 如何调用sklearn模块做交叉验证
终于搞明白了如何用sklearn做交叉验证!!! 一般在建立完模型之后,我们要预测模型的好坏,为了试验的可靠性(排除一次测试的偶然性)我们要进行多次测试验证,这时就要用交叉验证. sklearn中的s ...
- BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 23822 Solved: 6012[Submit][ ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题&&学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 9894 Solved: 4561[Subm ...
- c语言基础学习07
============================================================================= 涉及到的知识点有: 1.指针.指针的概念.指 ...