【解析HTML】HTML解析,網絡爬蟲

1、概述

  曾幾時,我仍是一個屌絲,一個在校大學生,高中的時候老師就對咱們撒了一個慌,說...。人們稱它爲一個善意的謊話,我卻傻傻信覺得正。高三的時候努力拼搏了一段時間,惋惜命運老是愛做弄人,高考考到了一個二流的大學,今後我告別了家鄉,踏上了大學校門,來到了一個鳥不生蛋但會拉屎的地方。剛來大學的時候,大一渾渾噩噩的度過,大門不錯,二門不邁,總體呆在宿舍打遊戲,打了大半年的遊戲,就那樣,大學裏最美好的日子離我遠去。往事不堪回首,過了一年,現在已經是學長了,做爲一個學長,我不甘落後,因而乎上課努力聽講,下課沒事和同窗去打球或是去圖書館學習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獲得咱們要的數據,固然,這種方式獲得的數據不推薦,同時也存在太多的侷限了,如:受網站的限制,解析困難等等。固然看了這篇文章解析就不是困難了,呵呵。瀏覽器

2、Jsoup和資源準備

jsoup介紹:服務器

 jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套很是省力的API,可經過DOM,CSS以及相似於jQuery的操做方法來取出和操做數據。網絡

主要功能:

  1. 從一個URL,文件或字符串中解析HTML;
  2. 使用DOM或CSS選擇器來查找、取出數據;
  3. 可操做HTML元素、屬性、文本;

jar包下載(兩種方式):

  1. 官網下載最新版:http://jsoup.org/download
  2. jsoup-1.8.3.jar(jar,doc和源碼)

jsoup更多信息查看官網:http://jsoup.org

3、HTML解析實戰

 新建一個Android項目(編碼設爲UTF-8),將下載的jsoup的jar包添加到項目的libs目錄下,並添加到構建路徑中,這裏因爲不打算開發一個完整的應用,因此用的開發工具是咱們更熟悉的eclipse,簡單點,不用Android Studio(as),用as也同樣。

做爲測試數據,咱們來爬一下這個網站:http://it.ithome.com/

訪問這個網站,能夠看到如今最新的頁面顯示以下,固然,它的文章會不斷更新,這是寫文章的時候的頁面(頁面的一部分):

這裏寫圖片描述

 咱們的任務是把文章的相關信息抓下來,包括:

  1. 文章左邊的圖片url
  2. 文章的標題article
  3. 文章的內容簡介summary
  4. 底部的關鍵字tags
  5. 右上角的發表時間postime

以下圖:

這裏寫圖片描述

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元素包含一篇文章的信息,解析重要方法說明:

  1. Document.select(String cssQuery):經過css選擇器獲取E元素集Elements
  2. Element.getElementsByTag(String tagName):經過標籤名稱獲取元素Elements
  3. Element.getElementsByClass(String className):經過標類選擇器獲取元素Elements
  4. Element.getElementById(String id):經過id獲取元素Element
  5. Element.attr(String attrName):經過屬性名獲取屬性值
  6. Element.text():獲取標籤元素的文本

 有js的DOM及JQuery編程經驗的人應該很容易理解上面的方法,更多的方法信息使用查看Jsoup官網文檔。

第三步:測試解析結果:

使用android單元測試:

  • 在AndroidManifest.xml添加instrumentation
<instrumentation android:targetPackage="com.jxust.lt.htmlparse" android:name="android.test.InstrumentationTestRunner"></instrumentation>
  • 在AndroidManifest.xml添加use-library
<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的步驟:

  1. 獲得Document對象:
  • 經過發送Jsoup的get或者post請求返回Document對象
  • 將html字符串轉換成Document對象(經過Jsoup.parse()方法):
  1. 使用Document.select()進行初步篩選數據

  2. 使用Element的一系列方法篩選出咱們要的數據

注意:要對照頁面源碼解析,解析任何數據以前咱們都得先知道要解析數據的結構,看着html頁面的源碼調用Document,Element等對象的相關方法怎麼簡單怎麼解析。

jsoup的get和post請求網絡在實際運用中使用很少,一般我會將jsoup和Volley,XUtils,Okhttp等著名的android網絡框架結合使用,即請求網絡用Volley等框架,解析用Jsoup,至少我就是這樣作的。

相關文章
相關標籤/搜索