曾幾時,我仍是一個屌絲,一個在校大學生,高中的時候老師就對咱們撒了一個慌,說...。人們稱它爲一個善意的謊話,我卻傻傻信覺得正。高三的時候努力拼搏了一段時間,惋惜命運老是愛做弄人,高考考到了一個二流的大學,今後我告別了家鄉,踏上了大學校門,來到了一個鳥不生蛋但會拉屎的地方。剛來大學的時候,大一渾渾噩噩的度過,大門不錯,二門不邁,總體呆在宿舍打遊戲,打了大半年的遊戲,就那樣,大學裏最美好的日子離我遠去。往事不堪回首,過了一年,現在已經是學長了,做爲一個學長,我不甘落後,因而乎上課努力聽講,下課沒事和同窗去打球或是去圖書館學習html,css,javascript,java,過着四點一線的生活,在大二一年裏拿了兩次獎學金。現在,已是大三...,時間還在流逝,如今仍是個屌絲,一個苦逼的大學生,還有事沒事喜歡爬各類網站,來知足本身那點小小的虛榮心...。好了,扯淡時間過,該寫代碼了。javascript
原諒我那點發自心裏的扯淡。下面咱們開始進入今天的主題,HTML解析和網絡爬蟲。css
什麼是html,網絡爬蟲?html
什麼是html這裏就很少說了,那麼什麼是網絡爬蟲呢?是否是在網絡上怕的蟲?哈哈,簡直是弱爆了,在前面扯淡的內容中提到了,我喜歡爬各類網站,我爬過我學校的官網和教務管理系統,爬過各類IT網站,作了個簡單的新聞客戶端。網絡爬蟲實際上是指自動地抓取萬維網信息的程序或者腳本,或者說是動態地抓取網站數據的程序。java
怎樣解析html?android
這裏咱們經過Java解析html的利器Jsoup解析html,使用jsoup輕鬆搞定html解析,讓你從一個從矮窮挫瞬間變身高大上,高端大氣上檔次。編程
爲何要解析html?json
咱們都知道如今網絡數據傳輸有三種經常使用的形式,xml,json(【JSON解析】JSON解析高手)和html,咱們的客戶端請求服務器,服務器一般給咱們返回上面三種形式的數據。同時若是是我的開發,因爲沒有本身的服務器,那麼咱們開發的應用程序就能夠經過爬別人的網站解析html獲得咱們要的數據,固然,這種方式獲得的數據不推薦,同時也存在太多的侷限了,如:受網站的限制,解析困難等等。固然看了這篇文章解析就不是困難了,呵呵。瀏覽器
jsoup介紹:服務器
jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套很是省力的API,可經過DOM,CSS以及相似於jQuery的操做方法來取出和操做數據。網絡
主要功能:
jar包下載(兩種方式):
jsoup更多信息查看官網:http://jsoup.org
新建一個Android項目(編碼設爲UTF-8),將下載的jsoup的jar包添加到項目的libs目錄下,並添加到構建路徑中,這裏因爲不打算開發一個完整的應用,因此用的開發工具是咱們更熟悉的eclipse,簡單點,不用Android Studio(as),用as也同樣。
做爲測試數據,咱們來爬一下這個網站:http://it.ithome.com/
訪問這個網站,能夠看到如今最新的頁面顯示以下,固然,它的文章會不斷更新,這是寫文章的時候的頁面(頁面的一部分):
咱們的任務是把文章的相關信息抓下來,包括:
以下圖:
OK,肯定好了咱們要抓取的信息後,咱們經過瀏覽器調試工具Firebug打開查看該頁面的源碼找到咱們關心數據的部分:
這個ul裏面的li第一個不是咱們想要的數據外,其餘的每一個li中都保存了一篇文章的信息。選擇其中兩個看看。
下面咱們能夠編寫解析代碼了。
第一步:新建JavaBean,Article.java
package com.jxust.lt.htmlparse; /** * 文章bean * @author lt * */ public class Article { private String title; // 標題 private String summary; // 文章內容簡介 private String imageUrl; // 圖片url private String tags; // 關鍵子 private String postime; // 發表時間 // setter... // getter... @Override public String toString() { return "Article [title=" + title + ", summary=" + summary + ", imageUrl=" + imageUrl + ", tags=" + tags + ", postime=" + postime + "]"; } }
第二步:新建一個工具類,HtmlParseUtil.java,寫一個鏈接網絡並解析返回的html頁面的方法:
/** * 請求網絡加載數據獲得文章的集合 * @param url:網站url */ public static List<Article> getArticles(String url){ List<Article> articles = new ArrayList<Article>(); Connection conn = Jsoup.connect(url); try { // 10秒超時時間,發起get請求,也能夠是post Document doc = conn.timeout(10000).get(); // 1. 只要咱們關心的信息數據,這裏使用css類選擇器 Element ul = doc.select(".ulcl").get(0); // 2. 獲得全部的li,排除個別不是同種類型的數據 Elements lis = ul.getElementsByTag("li"); for(int i=1;i<lis.size();i++){ // 經過FileBug發現這個網頁裏面第一個li不是咱們要的類型,因此從1開始 Article article = new Article(); Element li = lis.get(i); // 數據1,獲得圖片的url,經過img標籤的src屬性得到 Element img = li.getElementsByTag("img").first(); // 獲取標籤的屬性值,參數爲屬性名稱 String imageUrl = img.attr("src"); // 數據2,獲得文章的標題 Element h2 = li.getElementsByTag("h2").first(); // 取h2元素下面的第一個a標籤的文本即爲標題 String title = h2.getElementsByTag("a").first().text(); // 數據3,獲得文章的發表時間,取h2元素下面的第一個span標籤的文本即爲文章發表時間 String postime = h2.getElementsByTag("span").first().text(); // 數據4,獲得文章內容簡介,取li下面第一個p標籤的文本 String summary = li.getElementsByTag("p").first().text(); // 數據5,獲得文章的關鍵字,取li下面的class爲tags的第一個元素的全部的a標籤文本 Element tagsSpan = li.getElementsByClass("tags").first(); Elements tags = tagsSpan.getElementsByTag("a"); String key = ""; for(Element tag : tags){ key+=","+tag.text(); } // 去掉key的第一個","號 key = key.replaceFirst(",", ""); article.setTitle(title); article.setSummary(summary); article.setImageUrl(imageUrl); article.setPostime(postime); article.setTags(key); articles.add(article); } } catch (Exception ex) { ex.printStackTrace(); } return articles; }
在清單文件下添加請求網絡權限:
<uses-permission android:name="android.permission.INTERNET"/>
說明:請求網絡獲得Document對象後(不要導出包,是jsoup下的),經過select()方法帥選了class爲ulcl的ul元素,該頁面下只有一個class爲ulcl,ul下面第一個li不是咱們要的,排除,而後獲得每一個li對象,每一個li元素包含一篇文章的信息,解析重要方法說明:
有js的DOM及JQuery編程經驗的人應該很容易理解上面的方法,更多的方法信息使用查看Jsoup官網文檔。
第三步:測試解析結果:
使用android單元測試:
<instrumentation android:targetPackage="com.jxust.lt.htmlparse" android:name="android.test.InstrumentationTestRunner"></instrumentation>
<uses-library android:name="android.test.runner"/>
新建一個測試類HtmlParseTest.java繼承AndroidTestCase
寫一個測試方法:
public void testParseHtml(){ List<Article> articles = HtmlParseUtil.getArticles(url); for(int i=0;i<articles.size();i++){ Log.e("result"+i, articles.get(i).toString()); } }
這裏的url的值爲:"http://it.ithome.com/"
打開模擬器運行測試方法 Run As Android JUnit Test
日誌輸出結果:
...
能夠看到咱們獲得了20條數據,咱們來看看其中的一條
能夠看到文章標題,內容簡介,圖片url,關鍵字,發表時間5個咱們關心的數據全都解析出來了。到這裏html解析結束了,如今咱們有了數據,那麼咱們就能夠將數據顯示在listView中了(這裏不會將數據顯示在ListView中,這個很簡單,一個佈局一個適配器就搞定了,不懂的能夠問),從而能夠本身爲網站寫個新聞客戶端了,把要的數據全都抓取下來,體驗一下將別人的數據爲我所用的快樂,呵呵。
總結一下:
jsoup解析html的步驟:
使用Document.select()進行初步篩選數據
使用Element的一系列方法篩選出咱們要的數據
注意:要對照頁面源碼解析,解析任何數據以前咱們都得先知道要解析數據的結構,看着html頁面的源碼調用Document,Element等對象的相關方法怎麼簡單怎麼解析。
jsoup的get和post請求網絡在實際運用中使用很少,一般我會將jsoup和Volley,XUtils,Okhttp等著名的android網絡框架結合使用,即請求網絡用Volley等框架,解析用Jsoup,至少我就是這樣作的。