java判斷網頁的編碼格式,java判斷編碼格式

來源:互聯網
上載者:User

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 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<String, List<String>> headerFields = urlConn.getHeaderFields(); 42             // 判斷headers中是否存在Content-Type 43             if(headerFields.containsKey("Content-Type")){ 44                 //拿到header 中的 Content-Type :[text/html; charset=utf-8] 45                 List<String> 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<String> 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的依賴

<!-- 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包下載下來然後添加到該項目的環境中即可

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.