曾幾時,我還是個屌絲,一個在校大學生,高中的時候老師就對我們撒了一個慌,說...。人們稱它為善意的謊言,我卻傻傻信以為正。高三的時候努力拼搏了一段時間,可惜命運總是愛作弄人,高考考到了一個二流的大學,從此我告別了家鄉,踏上了大學校門,來到了一個鳥不生蛋但會拉屎的地方。剛來大學的時候,大一渾渾噩噩的度過,大門不錯,二門不邁,整體呆在宿舍打遊戲,打了大半年的遊戲,就那樣,大學裡最美好的日子離我遠去。往事不堪回首,過了一年,如今已是學長了,身為一個學長,我不甘落後,於是乎上課努力聽講,下課沒事和同學去打球或是去圖書館學習html,css,javascript,java,過著四點一線的生活,在大二一年拿了兩次獎學金。如今,已經是大三...,時間還在流逝,現在還是個屌絲,一個苦逼的大學生,還有事沒事喜歡爬各種網站,來滿足自己那點小小的虛榮心...。好了,扯淡時間過,該寫程式了。
原諒我那點發自內心的扯淡。下面我們開始進入今天的主題,HTML解析和網路爬蟲。
什麼是html,網路爬蟲?
什麼是html這裡就不多說了,那麼什麼是網路爬蟲呢?是不是在網路上怕的蟲?哈哈,簡直是弱爆了,在前面扯淡的內容中提到了,我喜歡爬各種網站,我爬過我學校的官網和教務管理系統,爬過各種IT網站,做了個簡單的新聞客戶端。網路爬蟲其實是指自動抓取萬維網資訊的程式或是腳本,或是動態地抓取網站資料的程式。
怎麼解析html?
這裡我們透過Java解析html的利器Jsoup解析html,使用jsoup輕鬆搞定html解析,讓你從一個從矮窮挫瞬間變身高大上,高端大氣上檔次。
為什麼要解析html?
我們都知道現在網路資料傳輸有三種常用的形式,xml,json(【JSON解析】 JSON解析高手)和html,我們的客戶端請求伺服器,伺服器通常會給我們返回上面三種形式的資料。同時如果是個人開發,由於沒有自己的伺服器,那麼我們開發的應用程式就可以透過爬別人的網站解析html得到我們要的數據,當然,這種方式得到的數據不推薦,同時也存在太多的局限了,如:受網站的限制,解析困難等等。當然看了這篇文章解析就不是困難了,呵呵。
jsoup介紹:
jsoup 是一款Java 的HTML解析器,可直接解析某個URL位址、HTML文字內容。它提供了一套非常省力的API,可透過DOM,CSS以及類似於jQuery的操作方法來取出和操作資料。
主要功能:
jar套件下載(兩種方式):
#官網下載最新版本:http://jsoup.org/download
jsoup-1.8.3.jar(jar,doc和原始碼)
jsoup 更多資訊查看官網:http://jsoup. org
新建一個Android專案(編碼設為UTF-8),將下載的jsoup的jar套件加入專案的libs目錄下,並加入到建置路徑中,這裡由於不打算開發一個完整的應用,所以用的開發工具是我們更熟悉的eclipse,簡單點,不用Android Studio(as),用as也一樣。
作為測試數據,我們來爬一下這個網站:http://it.ithome.com/
訪問這個網站,可以看到現在最新的頁面顯示如下,當然,它的文章會不斷更新,這是寫文章的時候的頁面(頁面的一部分):
# 我們的任務是把文章的相關資訊抓下來,包括:
文章左邊的圖片url
文章的標題article
文章的內容簡介summary
底部的關鍵字tags
右上角的發表時間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元素包含一篇文章的信息,解析重要方法說明:
Document.select(String cssQuery):透過css選擇器取得E元素集Elements
Element .getElementsByTag(String tagName):透過標籤名稱取得元素Elements
#Element.getElementsByClass(String className):透過標類選擇器取得元素Elements
#Element.getElementById(String id):透過id取得元素Element
#Element.attr(String attrName):透過屬性名稱取得屬性值
#Element.text():取得標籤元素的文字
有js的DOM及JQuery程式設計經驗的人應該很容易理解上面的方法,更多的方法資訊使用查看Jsoup官網文件。
第三步:測試解析結果:
使用android單元測試:
在AndroidManifest.xml加入instrumentation
<instrumentation android:targetPackage="com.jxust.lt.htmlparse" android:name="android.test.InstrumentationTestRunner"></instrumentation>
<uses-library android:name="android.test.runner"/>
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,關鍵字,發表時間5個我們關心的資料全都解析出來了。到這裡html解析結束了,現在我們有了數據,那麼我們就可以將數據顯示在listView中了(這裡不會將數據顯示在ListView中,這個很簡單,一個佈局一個適配器就搞定了,不懂的可以問),從而可以自己為網站寫個新聞客戶端了,把要的數據全都抓取下來,體驗一下將別人的數據為我所用的快樂,呵呵。
總結一下:
jsoup解析html的步驟:
得到Document物件:
post請求傳回Document物件
框架結合使用,即請求網絡用Volley等框架,解析用Jsoup,至少我就是這樣做的。
以上是HTML解析網頁爬蟲圖介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!