使用 xpath 解析 html 的解析器:Jsoupxpath
JsoupXpath 是一款純Java開發的使用xpath解析html的解析器,xpath語法分析與執行完全獨立,html的DOM樹生成借助Jsoup,故命名為JsoupXpath.為了在java里也享受xpath的強大與方便但又苦于找不到一款足夠強大的xpath解析器,故開發了JsoupXpath。JsoupXpath的實現邏輯清晰,擴展方便,支持幾乎全部常用的xpath語法.
http://www.cnblogs.com/ 為例 "http://a/@href"; "http://div[@id='paging_block']/div/a[text()='Next >']/@href"; "http://div[@id='paging_block']/div/a[text()*='Next']/@href"; "http://h1/text()"; "http://h1/allText()"; "http://h1//text()"; "http://div/a"; "http://div[@id='post_list']/div[position()<3]/div/h3/allText()"; "http://div[@id='post_list']/div[first()]/div/h3/allText()"; "http://div[@id='post_list']/div[1]/div/h3/allText()"; "http://div[@id='post_list']/div[last()]/div/h3/allText()"; //查找評論大于1000的條目(當然只是為了演示復雜xpath了,謂語中可以各種嵌套,這樣才能測試的更全面嘛) "http://div[@id='post_list']/div[./div/div/span[@class='article_view']/a/num()>1000]/div/h3/allText()"; //軸支持 "http://div[@id='post_list']/div[self::div/div/div/span[@class='article_view']/a/num()>1000]/div/h3/allText()"; "http://div[@id='post_list']/div[2]/div/p/preceding-sibling::h3/allText()"; "http://div[@id='post_list']/div[2]/div/p/preceding-sibling::h3/allText()|//div[@id='post_list']/div[1]/div/h3/allText()";
在這里暫不列出框架間的對比了,但我相信,你們用了會發現JsoupXpath就是目前市面上最強大的的Xpath解析器。
快速開始
如果不方便使用maven,可以直接使用lib下的依賴包跑起來試試,如方便可直接使用如下dependency(已經上傳至中央maven庫,最新版本0.1.1):
<dependency> <groupId>cn.wanghaomiao</groupId> <artifactId>JsoupXpath</artifactId> <version>0.1.1</version> </dependency>
依賴配置好后,就可以使用如下例子進行體驗了!
String xpath="http://div[@id='post_list']/div[./div/div/span[@class='article_view']/a/num()>1000]/div/h3/allText()";String doc = "..."; JXDocument jxDocument = new JXDocument(doc); List<Object> rs = jxDocument.sel(xpath); for (Object o:rs){ if (o instanceof Element){ int index = ((Element) o).siblingIndex(); System.out.println(index); } System.out.println(o.toString()); }
其他可以參考 cn.wanghaomiao.example包下的例子
語法
支持標準xpath語法(支持謂語嵌套),支持全部常用函數,支持全部常用軸,去掉了一些標準里面華而不實的函數和軸,下面會具體介紹。語法可以參考http://www.w3school.com.cn/xpath/index.asp
關于使用Xpath的一些注意事項
非常不建議直接粘貼Firefox或chrome里生成的Xpath,這些瀏覽器在渲染頁面會根據標準自動補全一些標簽,如table標簽會自動加上tbody標簽,這樣生成的Xpath路徑顯然不是最通用的,所以很可能就取不到值。所以,要使用Xpath并感受Xpath的強大以及他所帶來便捷與優雅最好就是學習下Xpath的標準語法,這樣應對各種問題才能游刃有余,享受Xpath的真正威力!
函數
<ULCLASS=>
-
text() 提取節點的自有文本
</li> -
node() 提取所有節點
</li> -
position() 返回當前節點所處在同胞中的位置
</li> -
last() 返回同級節點中的最后那個節點
</li> -
first() 返回同級節點中的第一個節點
</li> </ul>解析器擴展函數
<ULCLASS=>
-
allText()提取節點下全部文本,取代類似 //div/h3//text()這種遞歸取文本用法
</li> -
html()獲取全部節點的內部的html
</li> -
outerHtml()獲取全部節點的 包含節點本身在內的全部html
</li> -
num()抽取節點自有文本中全部數字,如果知道節點的自有文本(即非子代節點所包含的文本)中只存在一個數字,如閱讀數,評論數,價格等那么直接可以直接提取此數字出來。如果有多個數字將提取第一個匹配的連續數字。
</li> </ul>其他說明
-
contains(arga,argb)這個函數暫時不支持,因為JsoupXpath擁有強大的運算符支持,完全可以取代它!如,可以用*=取代contains() 例://div[text()*='next']
</li> </ul>軸
-
self 節點自身
</li> -
parent 父節點
</li> -
child 直接子節點
</li> -
ancestor 全部祖先節點 父親,爺爺 , 爺爺的父親...
</li> -
ancestor-or-self全部祖先節點和自身節點
</li> -
descendant 全部子代節點 兒子,孫子,孫子的兒子...
</li> -
descendant-or-self 全部子代節點和自身
</li> -
preceding-sibling 節點前面的全部同胞節點
</li> -
following-sibling 節點后面的全部同胞節點
</li> </ul>軸實用擴展
-
preceding-sibling-one 前一個同胞節點(擴展)
</li> -
following-sibling-one 返回下一個同胞節點(擴展) 語法
</li> -
sibling 全部同胞(擴展)
</li> </ul>操作符
這些操作符可謂足夠強大,滿足幾乎你所有的需求。
<ULCLASS=>
-
返回兩個節點集的并集
</li> -
a+b 加 返回數值結果
</li> -
a-b 減 返回數值結果
</li> -
a=b 判斷是否相等返回Boolean
</li> -
a!=b 不等于 返回Boolean
</li> -
a>b 大于 返回Boolean
</li> -
a>=b 大于等于 返回Boolean
</li> -
a<b 小于 返回Boolean
</li> -
a<=b 小于等于 返回Boolean
</li> </ul>操作符擴展
-
a^=b 字符串a是否以字符串b開頭 a startwith b 返回Boolean
</li> -
a*=b a是否包含b, a contains b 返回Boolean
</li> -
a$=b a是否以b結尾 a endwith b 返回Boolean
</li> -
a~=b a的內容是否符合 正則表達式b 返回Boolean
</li> </ul>其他說明
基本這些足夠了,其他雞肋的暫時不支持,如有特殊需求請聯系我。項目地址:GitHub/Jsoupxpath
</ULCLASS=></ULCLASS=></ULCLASS=>
-
-
-
-
-
-