使用java開源工具httpClient及jsoup抓取解析網頁資料,httpclientjsoup
今天做項目的時候遇到這樣一個需求,需要在網頁上展示今日黃曆資訊,資料格式如下
- 西曆時間:2016年04月11日 星期一
- 農曆時間:猴年三月初五
- 天干地支:丙申年 壬辰月 癸亥日
- 宜:求子 祈福 開光 祭祀 安床
- 忌:玉堂(黃道)危日,忌出行
主要包括西曆/農曆日期,以及忌宜資訊的等。但是手裡並沒有現成的資料可供使用,怎麼辦呢?
革命前輩曾經說過,沒有槍,沒有炮,敵(wang)人(luo)給我們造!網路上有很多現成的線上
萬年曆應用可供使用,雖然沒有現成介面,但是我們可以伸出手來,自己去拿。也就是所謂的資料
抓取。
這裡介紹兩個使用的工具,httpClient以及jsoup,簡介如下:
HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支援HTTP協議的用戶端編程工具包,並且它支援HTTP協議最新的版本和建議。HttpClient已經應用在很多的項目中,比如Apache Jakarta上很著名的另外兩個開源項目Cactus和HTMLUnit都使用了HttpClient。
httpClient使用方法如下:
1. 建立HttpClient對象。
2. 建立要求方法的執行個體,並指定請求URL。
3. 調用HttpClient對象的execute(HttpUriRequest request)發送請求,該方法返回一個HttpResponse。
4. 調用HttpResponse相關方法擷取相應內容。
5. 釋放串連。
jsoup 是一款 Java 的 HTML 解析器,可直接解析某個 URL 地址、HTML 常值內容。它提供了一套非常省力的 API,可通過 DOM,CSS 以及類似於 jQuery 的操作方法來取出和操作資料。
需要更多資訊可以參見官網
httpClient:http://hc.apache.org/httpcomponents-client-5.0.x/index.html
jsoup:http://jsoup.org/
接下來我們直接上代碼,這裡我們抓取2345線上萬年曆的資料 http://tools.2345.com/rili.htm
首先我們定義一個實體類Almanac來儲存黃曆資料
Almanac.java
1 package com.likx.picker.util.bean; 2 3 /** 4 * 萬年曆工具實體類 5 * 6 * @author 溯源blog 7 * 2016年4月11日 8 */ 9 public class Almanac {10 private String solar; /* 陽曆 e.g.2016年 4月11日 星期一 */11 private String lunar; /* 陰曆 e.g. 猴年 三月初五*/12 private String chineseAra; /* 天干地支紀年法 e.g.丙申年 壬辰月 癸亥日*/13 private String should; /* 宜e.g. 求子 祈福 開光 祭祀 安床*/14 private String avoid; /* 忌 e.g. 玉堂(黃道)危日,忌出行*/15 16 public String getSolar() {17 return solar;18 }19 20 public void setSolar(String date) {21 this.solar = date;22 }23 24 public String getLunar() {25 return lunar;26 }27 28 public void setLunar(String lunar) {29 this.lunar = lunar;30 }31 32 public String getChineseAra() {33 return chineseAra;34 }35 36 public void setChineseAra(String chineseAra) {37 this.chineseAra = chineseAra;38 }39 40 public String getAvoid() {41 return avoid;42 }43 44 public void setAvoid(String avoid) {45 this.avoid = avoid;46 }47 48 public String getShould() {49 return should;50 }51 52 public void setShould(String should) {53 this.should = should;54 }55 56 public Almanac(String solar, String lunar, String chineseAra, String should,57 String avoid) {58 this.solar = solar;59 this.lunar = lunar;60 this.chineseAra = chineseAra;61 this.should = should;62 this.avoid = avoid;63 }64 }
然後是抓取解析的主程式,寫程式之前需要在官網下載需要的jar包
AlmanacUtil.java
package com.likx.picker.util;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import org.apache.http.HttpEntity;import org.apache.http.ParseException;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;/** *<STRONG>類描述</STRONG> : 2345萬年曆資訊爬取工具<p> * * @version 1.0 <p> * @author 溯源blog * * <STRONG>建立時間</STRONG> : 2016年4月11日 下午14:15:44<p> * <STRONG>修改曆史</STRONG> :<p> *<pre> * 修改人 修改時間 修改內容 * --------------- ------------------- ----------------------------------- *</pre> */public class AlmanacUtil { /** * 單例工具類 */ private AlmanacUtil() { } /** * 擷取萬年曆資訊 * @return */ public static Almanac getAlmanac(){ String url="http://tools.2345.com/rili.htm"; String html=pickData(url); Almanac almanac=analyzeHTMLByString(html); return almanac; } /* * 爬取網頁資訊 */ private static String pickData(String url) { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpGet httpget = new HttpGet(url); CloseableHttpResponse response = httpclient.execute(httpget); try { // 擷取響應實體 HttpEntity entity = response.getEntity(); // 列印響應狀態 if (entity != null) { return EntityUtils.toString(entity); } } finally { response.close(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關閉串連,釋放資源 try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } /* * 使用jsoup解析網頁資訊 */ private static Almanac analyzeHTMLByString(String html){ String solarDate,lunarDate,chineseAra,should,avoid=" "; Document document = Jsoup.parse(html); //西曆時間 solarDate=getSolarDate(); //農曆時間 Element eLunarDate=document.getElementById("info_nong"); lunarDate=eLunarDate.child(0).html().substring(1,3)+eLunarDate.html().substring(11); //天干地支紀年法 Element eChineseAra=document.getElementById("info_chang"); chineseAra=eChineseAra.text().toString(); //宜 should=getSuggestion(document,"yi"); //忌 avoid=getSuggestion(document,"ji"); Almanac almanac=new Almanac(solarDate,lunarDate,chineseAra,should,avoid); return almanac; } /* * 擷取忌/宜 */ private static String getSuggestion(Document doc,String id){ Element element=doc.getElementById(id); Elements elements=element.getElementsByTag("a"); StringBuffer sb=new StringBuffer(); for (Element e : elements) { sb.append(e.text()+" "); } return sb.toString(); } /* * 擷取西曆時間,用yyyy年MM月dd日 EEEE格式表示。 * @return yyyy年MM月dd日 EEEE */ private static String getSolarDate() { Calendar calendar = Calendar.getInstance(); Date solarDate = calendar.getTime(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 EEEE"); return formatter.format(solarDate); }}
為了簡單明了我把抓取解析抽象成了幾個獨立的方法,
其中pickData()方法使用httpClient來抓取資料到一個字串中(就是在網頁上點擊查看原始碼看到的HTML源碼),
analyzeHTMLByString()方法來解析抓取到的字串,getSuggestion方法把抓取方法類似的宜忌資料抽象到了
一起,另外因為西曆時間可以很容易的自己產生就沒有在網頁上爬取。
然後下面是一個測試類別簡單測試下效果:
AlmanacUtilTest.java
package com.likx.picker.util.test;public class AlmanacUtilTest { public static void main(String args[]){ Almanac almanac=AlmanacUtil.getAlmanac(); System.out.println("西曆時間:"+almanac.getSolar()); System.out.println("農曆時間:"+almanac.getLunar()); System.out.println("天干地支:"+almanac.getChineseAra()); System.out.println("宜:"+almanac.getShould()); System.out.println("忌:"+almanac.getAvoid()); }}
運行結果如下:
整合到實際項目中效果是這樣的:
另外最近部落格一直沒怎麼更新,因為最近考慮到技術氛圍的原因,離開了對日外包行業,前往
一家互連網公司就職。說一下最近的感受,那就是一個程式員最核心的競爭力不是學會了多少架構,
掌握多少種工具(當然這些對於程式員也不可或缺),而是紮實的基礎以及快速學習的能力,比如今天
這個項目,從對httpClient,jsoup工具一無所知到編寫出Demo代碼總計大概1個多小時,在之前對於
我來說是不可想象的,在技術氛圍濃厚的地方快速get技能的感覺,非常好。
當然本例只是一個非常淺顯的小例子,網頁上內容也很容易抓取,httpClient及jsoup工具更多強大
的地方沒有體現到,比如httpClient不僅可以發送get請求,而且可以發送post請求,提交表單,傳送
檔案,還比如jsoup最強大的地方在於它支援仿jquery的選取器。本例僅僅使用了最簡單的document.getElementById()
匹配元素,實際上jsoup的選取器異常強大,可以說它就是java版的jquery,比如這樣:
Elements links = doc.select("a[href]"); // a with hrefElements pngs = doc.select("img[src$=.png]"); // img with src ending .pngElement masthead = doc.select("div.masthead").first(); // div with class=mastheadElements resultLinks = doc.select("h3.r > a"); // direct a after h3
另外還有很多強大的功能水平有限就不一一列舉了,感興趣的可以參照官網文檔,也歡迎交流指正。新技能get起來!
本文著作權歸作者及部落格園所有,轉載請註明作者及原文出處
溯源blog http://www.cnblogs.com/lkxsnow/