由於很多原因,我們要獲取網頁的編碼(多半是寫批量抓取的腳本吧...嘻嘻嘻)
注意:
如果你的目的是獲取不亂碼的網頁內容(而不是根據網址發送post請求獲取返回值),切記切記,移步這里
java根據URL獲取HTML內容
先說思路:
有三種方法:
1,根據responseHeaders獲取Content-Type里的charset,如下圖
這種方法最好,最推薦,然而,很多網站都沒有,要么是像百度這樣:
有Content-Type,然而沒有指定charset
要么是像博客園這樣:
???Content-Type都不給我么...???
所以雖然這種方法最准確.但是...並不是每個網站都有的...
2.根據html標簽里的meta取
這里還以百度為例:
怎么取標簽,我就不說了,如果不會就留言,如有需要我再寫博客(然而也沒什么人看我博客,更沒什么人會留言...悲傷...我就默認你們都會取了)
雖然中文亂碼,但是英文是不亂的,哪怕你不知道編碼,隨便用個GBK,UTF-8都能取...
但是,這種方法不准...不保證一定能取到正確的
並且..由於這種方法你還得拿到HTML內容...所以,還得判斷一下是不是GZIP方式壓縮了...賊麻煩...所以我就放棄了
3.通過第三方庫,去猜格式
這種方法,原則上講是存在一定的猜錯幾率的...
原理是同時進行多種編碼的嘗試(gb2312啊,utf-8啊,windows-XXXX啊),哪個先返回正確的格式就認定是哪個...雖然根據我的嘗試很准,然而理論上還是會不貼切的,沒有第一種准.
文件下載:http://files.cnblogs.com/files/blog5277/cpdetector_1.0.10_binary.zip
切記切記,總共是4個jar包...別的教程里並沒有告訴我,害得我分別去找這三個編碼jar包,好氣...最后才發現原來就在這個壓縮包里...吃了眼瞎的虧了
這四個jar包放進你項目里就行
最后,經過慎重的考慮與取舍,我決定先用第一種方法取(畢竟最准確),放棄第二種方法(賊麻煩...),第一種取不到了,再用第三種猜,如下
public static String getUrlCharset(String url){ try { String urlNameString = url; URL realUrl = new URL(urlNameString); // 打開和URL之間的連接 URLConnection connection = realUrl.openConnection(); // 設置通用的請求屬性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立實際的連接 connection.connect(); // 獲取所有響應頭字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍歷所有的響應頭字段 System.out.println("Content-Type" + "--->" + map.get("Content-Type")); List<String> list=map.get("Content-Type"); if (list.size()>0){ String contentType=list.toString().toUpperCase(); if (contentType.contains("UTF-8")){ return "UTF-8"; } if(contentType.contains("GB2312")){ return "GB2312"; } if (contentType.contains("GBK")){ return "GBK"; } } //如果相應頭里面沒有編碼格式,用下面這種 CodepageDetectorProxy codepageDetectorProxy = CodepageDetectorProxy.getInstance(); codepageDetectorProxy.add(JChardetFacade.getInstance()); codepageDetectorProxy.add(ASCIIDetector.getInstance()); codepageDetectorProxy.add(UnicodeDetector.getInstance()); codepageDetectorProxy.add(new ParsingDetector(false)); codepageDetectorProxy.add(new ByteOrderMarkDetector()); Charset charset = codepageDetectorProxy.detectCodepage(new URL(url)); return charset.name(); }catch (Exception e){} return null; }
如果返回值是null,那很不幸,我也不知道哪里出異常了,自己debug解決吧,嘻嘻.一般是沒事.最多就是網絡不好timeout了
就這樣