Android爬蟲程式應用實作(使用Jsoup)
網路爬蟲(Web crawler)是一種可以按照一定的規則,自動地抓取全球資訊網資訊的程式或者指令碼,它們被廣泛用於網際網路搜尋引擎或其他類似網站,用於自動採集所有其能夠訪問到的頁面內容,以獲取或更新這些網站的內容和檢索方式。從功能上來講爬蟲軟體可以簡易分成 資料採集 , 處理 , 儲存 三個部分,傳統的爬蟲作法是從一個或若干個網頁URL開始,通過Http向目標發出請求的Request,等待伺服器回應Response, Response的內容可能有Html 、Json 、JavaScript 等, 取得Response後若為HTML可以透過網頁解析取得目標資訊,再將其儲存後做進一步的處理,若取得為JSON則可將之轉成物件後取得目標內容.
Jsoup介紹
Jsoup是一個Java的開源Html解析器,他提供一套非常方便的API可以通過URL取的該網頁的HTML文本,並可以使用類似Jquery的函示取出我們抓取到的HTML內部的資訊.官網(https://jsoup.org/)明確述說Jsoup可以做到以下幾點
- 從網路連結 (URL)、檔案及字串中解析 HTML
- 使用 DOM 遍歷或 CSS 的選擇器來尋找資料
- 操縱 HTML 元素、屬性和文字
- 避免 XSS 攻擊
- 輸出簡潔的 HTML
下文起我們將使用Jsoup實作Android爬蟲軟體.一樣我們先預設我們的目標.我們將使用爬蟲去爬取昕力大學的論壇,https://www.tpisoftware.com/tpu/)並將已發布的文章擷取下來作列表顯示.過程將不使用本地資源,全程由論壇資源提供!
首先,我們先於Android Grande 中加入Jsoup套件,當前最新版本為1.13.1版本
另外必須要在AndroidManifest.xml中加入以下權限
1:Android.permission.INTERTNET
2:Android.permission.ACCESS_NETWORK_STATE
爬取資料前先檢察網路是否處於連線狀況才進行資料擷取
Andriod在4.0版本後如果你在MainThread中執行http請求,會回報android.os.NetworkOnMainThreadException異常,因此我們需要另外開Thread去執行http請求.
執行完後結果如下圖,先以TextView輸出文字,可以觀察到我們已經將昕力大學論壇網址(https://www.tpisoftware.com/tpu/index)內部HTML碼已經被我們取回.
HTML擷取完成後,接著我們將要開始分析擷取下來的網頁內碼,取出我們需要的資訊再利用,本次我們目標是要取出文章主題 、縮圖、作者、發布時間.
我可以透過瀏覽器(筆者是使用Google Chrome瀏覽器),在該網頁點擊F12按鍵,開啟開發者模式,上方置頂選單選擇Elements,即可以看到該網頁於瀏覽器內部顯示之Html內碼,該內碼約同等於我們上方程式碼截取到之Html內碼.點擊置頂選單滑鼠標誌可以讓我們透過點擊,直接對應至點擊處的HTML內碼.
這邊我們可以簡短敘說一下HTML程式語法,方便完全沒有從事網頁工程的學員可以明白我們如何擷取上述要擷取的必要訊息.
HTML( HyperText Markup Language ,超文本標記語言 )是一種建立網頁的標記語言,他本身已經定義好了標籤(Tags):<p>、<div>、<span>、<img> 我們將之稱為元素(element) , 我們用元素來控制內容的呈現樣貌,例如字體大小、斜體粗體、在文字或圖片設置超連結等.
簡單的HTML範例為例
<div class=“ClassName” > example for div! </div>
(1) (2) (3) (4)
1. div :我們起始標籤內容,被< > 夾住,為網頁識別標籤
2. class. : 標籤(div)內部屬性(Attribute)標示該屬性名稱,也可用於對映css佈局
3. content :存於起始標籤後方,結束標籤前方,即為我們網頁將呈現的內容
4. /div :結束標籤,前方必有一個“/”.
回到我們透過瀏覽器擷取的內容
內碼看起來似乎很雜亂,但我們將它依照上述HTML規則進行探索,我們可以找出生成此網頁的HTML是具有規律的.我們依據我們想抓取的目標可以整理成以下對映圖
如此,我們需要抓取的目標及很明顯的顯示.接著開始使用Jsoup將目標取出,程式實際運作如下
此部分我們使用Jsoup提供的Api,來分離出我們所需要的資料,以下只略述有使用的API
getElementsByClass(“card-article”):取出Html中所有屬性之Class名為card-article之元素.
getElementsByClass(“article-img”).select(“img”).attr("src"):取出aricle-img元素後擷取內部圖片網址.
getElementsByClass(“article-img”).select(“span.date”).text():取出aricle-img元素,取其內部span屬性內部名為date內部資訊.
其他額外的API,學員可以在官網 https://jsoup.org/apidocs/org/jsoup/nodes/Element.html#appendText(java.lang.String) 中查詢.
完成汲取必要資料後我們,後續我們僅只需要使用recycleview將剛剛擷取資料作呈現即可!程式碼如下
Main.xml
RecycleView
最終程式呈現結果
最後可以看到我們Resource資源沒有放任何東西,全部的資訊皆取於網頁上資料!
Reference
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/45275/
http://www.android5.online/Android/androidjc/gyandroid/201603/13535.html
https://codertw.com/android-%E9%96%8B%E7%99%BC/337867/
https://songlee24.github.io/2015/01/11/android-crawler/
https://www.open-open.com/jsoup/dom-navigation.htm
https://jsoup.org/apidocs/org/jsoup/nodes/Element.html#appendText(java.lang.String)
HTML
https://developer.mozilla.org/zh-TW/docs/Learn/Getting_started_with_the_web/HTML_basics
程式(自己code 需要同仁可以自取)
https://drive.google.com/file/d/1IjFvMDDPbzBbPr_LwtIRVyRWTz5eSvNt/view?usp=sharing