博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java判断网页的编码格式
阅读量:5334 次
发布时间:2019-06-15

本文共 7244 字,大约阅读时间需要 24 分钟。

在爬取内容时,遇到乱码问题。故需对网页内容编码格式做判断,方式大体分为三种:一、从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)下载。整个代码如下:

1 import info.monitorenter.cpdetector.io.ASCIIDetector;  2 import info.monitorenter.cpdetector.io.ByteOrderMarkDetector;  3 import info.monitorenter.cpdetector.io.CodepageDetectorProxy;  4 import info.monitorenter.cpdetector.io.JChardetFacade;  5 import info.monitorenter.cpdetector.io.ParsingDetector;  6 import info.monitorenter.cpdetector.io.UnicodeDetector;  7   8 import java.io.ByteArrayInputStream;  9 import java.io.IOException; 10 import java.io.InputStream; 11 import java.net.MalformedURLException; 12 import java.net.URL; 13 import java.net.URLConnection; 14 import java.nio.charset.Charset; 15 import java.util.List; 16 import java.util.Map; 17  18 import org.apache.commons.io.IOUtils; 19  20 public class PageEncoding { 21     /**    测试用例 22      * @param args 23      */ 24     public static void main(String[] args) { 25          26         String charset = getEncodingByContentStream("http://www.baidu.com"); 27          28         System.out.println(charset); 29     } 30  31     /** 32      * 从header中获取页面编码 33      * @param strUrl 34      * @return 35      */ 36     public static String getEncodingByHeader(String strUrl){ 37         String charset = null; 38         try { 39             URLConnection urlConn = new URL(strUrl).openConnection(); 40             // 获取链接的header 41             Map
> headerFields = urlConn.getHeaderFields(); 42 // 判断headers中是否存在Content-Type 43 if(headerFields.containsKey("Content-Type")){ 44 //拿到header 中的 Content-Type :[text/html; charset=utf-8] 45 List
attrs = headerFields.get("Content-Type"); 46 String[] as = attrs.get(0).split(";"); 47 for (String att : as) { 48 if(att.contains("charset")){ 49 // System.out.println(att.split("=")[1]); 50 charset = att.split("=")[1]; 51 } 52 } 53 } 54 return charset; 55 } catch (MalformedURLException e) { 56 e.printStackTrace(); 57 return charset; 58 } catch (IOException e) { 59 e.printStackTrace(); 60 return charset; 61 } 62 } 63 64 /** 65 * 从meta中获取页面编码 66 * @param strUrl 67 * @return 68 */ 69 public static String getEncodingByMeta(String strUrl){ 70 String charset = null; 71 try { 72 URLConnection urlConn = new URL(strUrl).openConnection(); 73 //避免被拒绝 74 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"); 75 // 将html读取成行,放入list 76 List
lines = IOUtils.readLines(urlConn.getInputStream()); 77 for (String line : lines) { 78 if(line.contains("http-equiv") && line.contains("charset")){ 79 // System.out.println(line); 80 String tmp = line.split(";")[1]; 81 charset = tmp.substring(tmp.indexOf("=")+1, tmp.indexOf("\"")); 82 }else{ 83 continue; 84 } 85 } 86 return charset; 87 } catch (MalformedURLException e) { 88 e.printStackTrace(); 89 return charset; 90 } catch (IOException e) { 91 e.printStackTrace(); 92 return charset; 93 } 94 } 95 96 /** 97 * 根据网页内容获取页面编码 98 * case : 适用于可以直接读取网页的情况(例外情况:一些博客网站禁止不带User-Agent信息的访问请求) 99 * @param url100 * @return101 */102 public static String getEncodingByContentUrl(String url) {103 CodepageDetectorProxy cdp = CodepageDetectorProxy.getInstance();104 cdp.add(JChardetFacade.getInstance());// 依赖jar包 :antlr.jar & chardet.jar105 cdp.add(ASCIIDetector.getInstance());106 cdp.add(UnicodeDetector.getInstance());107 cdp.add(new ParsingDetector(false));108 cdp.add(new ByteOrderMarkDetector());109 110 Charset charset = null;111 try {112 charset = cdp.detectCodepage(new URL(url));113 } catch (MalformedURLException e) {114 e.printStackTrace();115 } catch (IOException e) {116 e.printStackTrace();117 }118 System.out.println(charset);119 return charset == null ? null : charset.name().toLowerCase();120 }121 122 /**123 * 根据网页内容获取页面编码124 * case : 适用于不可以直接读取网页的情况,通过将该网页转换为支持mark的输入流,然后解析编码125 * @param strUrl126 * @return127 */128 public static String getEncodingByContentStream(String strUrl) {129 Charset charset = null;130 try {131 URLConnection urlConn = new URL(strUrl).openConnection();132 //打开链接,加上User-Agent,避免被拒绝133 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");134 135 //解析页面内容136 CodepageDetectorProxy cdp = CodepageDetectorProxy.getInstance();137 cdp.add(JChardetFacade.getInstance());// 依赖jar包 :antlr.jar & chardet.jar138 cdp.add(ASCIIDetector.getInstance());139 cdp.add(UnicodeDetector.getInstance());140 cdp.add(new ParsingDetector(false));141 cdp.add(new ByteOrderMarkDetector());142 143 InputStream in = urlConn.getInputStream();144 ByteArrayInputStream bais = new ByteArrayInputStream(IOUtils.toByteArray(in));145 // detectCodepage(InputStream in, int length) 只支持可以mark的InputStream146 charset = cdp.detectCodepage(bais, 2147483647);147 } catch (MalformedURLException e) {148 e.printStackTrace();149 } catch (IOException e) {150 e.printStackTrace();151 }152 return charset == null ? null : charset.name().toLowerCase();153 }154 }

注意的点:

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的依赖

info.monitorenter.cpdetector
cpdetector
1.0.10

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

antlr
antlr
2.7.7
net.sourceforge.jchardet
jchardet
1.0

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

转载于:https://www.cnblogs.com/san-ge/p/8409493.html

你可能感兴趣的文章
LightOJ - 1151 Snakes and Ladders
查看>>
Codeforces 1179 D - Fedor Runs for President
查看>>
HDU 6184 Counting Stars
查看>>
AtCoder Beginner Contest 133 F Colorful Tree
查看>>
算法笔记--BSGS && exBSGS 模板
查看>>
P5043 【模板】树同构([BJOI2015]树的同构)
查看>>
Codeforces 348 D - Turtles
查看>>
bzoj 2321 星器
查看>>
HDU 6568 Math
查看>>
BZOJ 4488: [Jsoi2015]最大公约数
查看>>
算法笔记--笛卡尔树模板
查看>>
2018年长沙理工大学第十三届程序设计竞赛 I 连续区间的最大公约数
查看>>
AcWing 246. 区间最大公约数
查看>>
算法笔记--线性基求交模板
查看>>
BZOJ 2154: Crash的数字表格
查看>>
The 2019 Asia Nanchang First Round Online Programming Contest The Nth Item
查看>>
BZOJ1413 [ZJOI2009]取石子游戏
查看>>
「模拟8.21」虎
查看>>
「模拟8.23」阴阳 DP
查看>>
「模拟8.21」山洞(矩阵优化DP)
查看>>