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