1. 程式人生 > >JAVA jsoup 爬蟲 傻瓜入門實錄 (2-1) 選擇器 Selector 實務分解說明

JAVA jsoup 爬蟲 傻瓜入門實錄 (2-1) 選擇器 Selector 實務分解說明

JAVA jsoup 爬蟲 傻瓜入門實錄 (2-1) 選擇器 Selector 實務分解說明

這部分要講解的是個人常用的jsoup選擇器說明

上一篇我們講完各種型態解析成Document型態的方法實做

當我們解析成Document後 就可以開始做爬蟲的動作

爬蟲前我們應該先分析要抓取的網頁資料

你要抓的資料是在哪個div、哪個table

那個div是否有特定的id、class等等

由於公司我們抓匯的目的有個前提也要是能長時間自動抓匯

所以也要判斷要抓取的資料區域是否會隨時間改變 也盡量把所有可能的變因加上去 雖然每幾個月網頁資料或多或少還是有變化的地方 但是盡可能的縮小之後要修改程式的複雜程度

以下用一個以前的案子作範例 特別挑了一個較簡單的

要抓匯的位置就是基金產品裡的資料

分析後發現需要的資料都包含在這個class為”fund-jztable”的div tag中

因此第一目標就是先縮小區塊 把這個div先抓出來 後續再另外處理個別專案

String htmlPage = Jsoup.connect(“http://www.bdfund.com.cn/").get().toString();
Document doc = Jsoup.parse(htmlPage); //先做jsoup parse轉Document

這裡開始第一次使用到jsoup中非常強大的查詢功能:選擇器Selector

Elements divtags = doc.select(“div.fund-jztable”);

直接從案例說明 我們把剛剛做的步驟開始分解說明

如上述 我們要抓的tag是div 這個div的class是"fund-jztable"

因此我們從原本pasered的doc下select的方法 去選擇到div的tag

doc.select(“div”)

此時抓到的是網頁中所有div的tag 而經過select方法後出來的型態為Elements

我自己是把Elements想像成一個沒有間隔的array

Elements把所有div tag的區塊全部存入其中

一個div就是一個Element 所有的Element就組成此時Elements

這個是從案例面來講

總觀來講select方法找到的是你要指定的tag標籤(<a>,<div>,<table>….)

而這樣的寫法抓到的會是這個頁面所有包含你指定的標籤 包成一個Elements

Elements裡面並不是雜亂無章 你可以再額外篩出這堆相同標籤中 你要的指定專案

此時就講到第二部分

doc.select(“div.fund-jztable”)

這邊可以看到 有別於第一部分 這邊加入了class name 也就是我們真正要抓取的區塊

這種寫法你可以直接從網頁中一大堆相同tag中 找到你要的部分

但是前提是你必須判斷那個部分獨有的部分

如果這個class不只有這個地方出現 可能下面還有好幾個div同時也擁有這個class name 你抓出的將會是多個div區塊 而不是我們想要的單區塊

也因此 事前的分析非常重要 如果過於簡化剛開始分析的動作 很有可能做到一半才發現前面的步驟全都徒勞無功

上述案例 已經確認這個class name 是唯一 所以直接抓取這個class

而這是抓取class的寫法 實際上 在做抓取時 可能會要抓這個tag的id, attr等等

class

tagName.className //點前面為標籤名稱(a,div...) 點之後為class名稱

而下面再多提幾個我自己常用到的寫法

id

tagName#idName //#後接id名稱
//e.g doc.select(“a.myStatistics”)

attr

attr這邊必須多做敘述 attr也有許多寫法

純取所有指定attr屬性名稱

tagName[attrName] //[]中先寫入attr名稱
//e.g doc.select(“a[href]”)

指定attr屬性的值

tagName[attrName = attrValue] //[]中先寫入attr名稱 =後接value
//e.g doc.select(“a[href=google.com]”)

attr也可以搭配正規表示法 ^開頭 $結尾 *包含符號做查詢

[attrName ^= attrvalue] //以這個屬性值為開頭的所有元素
[attrName $= attrvalue] //以這個屬性值為結尾的所有元素
[attrName *= attrvalue] //包含這個屬性值的所有元素
[attrName ~= regularExpression] //正規表示法
這邊是我個人常用到的 還有更多寫法可以參考

這邊再補充一個點

其實可以把tag後面的所有name想成是attr 而value就是這個attr的value

舉個例

doc.select(“div.fund-jztable”)

你也可以想成

doc.select(“div[class=fund-jztable]”)

順便一提 其實這個select用法 用getElementsByTag也能達到相同的效果

doc.getElementsByTag(tagName);
doc.select(tagName);

兩者的差別在於 select可以直接一句話解決tag後面各種指定value的抓取

如果用getElementsBy可能又得先抓ByTag再拆開抓其他需要的value等等

不過因為getElementsBy可以ById,ByAttribute 可以直接跳過tag 找後面的value

像是Attribute也有詳細的方法可以做getElementsByAttributeStarting,ending,match等等

看自己習慣跟用途吧