java获取网页编码_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)下载。整个代码如下:

1 importinfo.monitorenter.cpdetector.io.ASCIIDetector;2 importinfo.monitorenter.cpdetector.io.ByteOrderMarkDetector;3 importinfo.monitorenter.cpdetector.io.CodepageDetectorProxy;4 importinfo.monitorenter.cpdetector.io.JChardetFacade;5 importinfo.monitorenter.cpdetector.io.ParsingDetector;6 importinfo.monitorenter.cpdetector.io.UnicodeDetector;7

8 importjava.io.ByteArrayInputStream;9 importjava.io.IOException;10 importjava.io.InputStream;11 importjava.net.MalformedURLException;12 importjava.net.URL;13 importjava.net.URLConnection;14 importjava.nio.charset.Charset;15 importjava.util.List;16 importjava.util.Map;17

18 importorg.apache.commons.io.IOUtils;19

20 public classPageEncoding {21 /**测试用例22 *@paramargs23 */

24 public static voidmain(String[] args) {25

26 String charset = getEncodingByContentStream("http://www.baidu.com");27

28 System.out.println(charset);29 }30

31 /**

32 * 从header中获取页面编码33 *@paramstrUrl34 *@return

35 */

36 public staticString getEncodingByHeader(String strUrl){37 String charset = null;38 try{39 URLConnection urlConn = newURL(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 returncharset;55 } catch(MalformedURLException e) {56 e.printStackTrace();57 returncharset;58 } catch(IOException e) {59 e.printStackTrace();60 returncharset;61 }62 }63

64 /**

65 * 从meta中获取页面编码66 *@paramstrUrl67 *@return

68 */

69 public staticString getEncodingByMeta(String strUrl){70 String charset = null;71 try{72 URLConnection urlConn = newURL(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 returncharset;87 } catch(MalformedURLException e) {88 e.printStackTrace();89 returncharset;90 } catch(IOException e) {91 e.printStackTrace();92 returncharset;93 }94 }95

96 /**

97 * 根据网页内容获取页面编码98 * case : 适用于可以直接读取网页的情况(例外情况:一些博客网站禁止不带User-Agent信息的访问请求)99 *@paramurl100 *@return

101 */

102 public staticString getEncodingByContentUrl(String url) {103 CodepageDetectorProxy cdp =CodepageDetectorProxy.getInstance();104 cdp.add(JChardetFacade.getInstance());//依赖jar包 :antlr.jar & chardet.jar

105 cdp.add(ASCIIDetector.getInstance());106 cdp.add(UnicodeDetector.getInstance());107 cdp.add(new ParsingDetector(false));108 cdp.add(newByteOrderMarkDetector());109

110 Charset charset = null;111 try{112 charset = cdp.detectCodepage(newURL(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 *@paramstrUrl126 *@return

127 */

128 public staticString getEncodingByContentStream(String strUrl) {129 Charset charset = null;130 try{131 URLConnection urlConn = newURL(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.jar

138 cdp.add(ASCIIDetector.getInstance());139 cdp.add(UnicodeDetector.getInstance());140 cdp.add(new ParsingDetector(false));141 cdp.add(newByteOrderMarkDetector());142

143 InputStream in =urlConn.getInputStream();144 ByteArrayInputStream bais = newByteArrayInputStream(IOUtils.toByteArray(in));145 //detectCodepage(InputStream in, int length) 只支持可以mark的InputStream

146 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包下载下来然后添加到该项目的环境中即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值