<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SipSoup基于Jsoup的xpath實現(xiàn)

          聯(lián)合創(chuàng)作 · 2023-09-29 22:40

          sipsoup是一個基于Jsoup的xpath實現(xiàn),他將Jsoup的cssQuery變成了xpath語法的一部分,可以實現(xiàn)在xpath內(nèi)部執(zhí)行cssQuery和xpath混合模式的鏈式文檔查詢

          是一款純Java開發(fā)的使用xpath解析html的解析器,xpath語法分析與執(zhí)行完全獨立,html的DOM樹生成借助Jsoup。

          sipSoup本身也應(yīng)該叫做Xsoup,JsoupXpath之類的,但是他出身太晚了,名字被占了,但是我覺得還是應(yīng)該喝湯,所以我喜歡sipSoup這個名字。

          每一個爬蟲框架作者都應(yīng)該實現(xiàn)一個xpath, sipsoup 出現(xiàn)也是如此,在我設(shè)計爬蟲框架vscrawler的時候,考慮如何定位抽取數(shù)據(jù),甚至如何整合其他爬蟲框架的抽取API, 然后調(diào)研了Xsoup和JsoupXpath,看到JsoupXpath眼前一亮,我覺得他肯定適合我的需要,所以嘗試使用JsoupXpath對接了Xsoup,因為JsoupXpath實現(xiàn)了xpath2.0的絕大部分語法功能, 使用JsoupXpath可以非常靈活自由的實現(xiàn)xpath。但是在整合的過程,我發(fā)現(xiàn)JsoupXpath有一點不符合我的需求,就是他都是運行的適合拋錯,我希望能夠在編譯xpath表達式的時候,就可以做語法 檢查,我希望JsoupXpath可以類似Xsoup一樣做鏈式抽取,我希望規(guī)則模型可以緩存。所以嘗試著對JsopXpath進行重構(gòu)。

          SipSoup本質(zhì)是對JsoupXpath重構(gòu)而來的,里面少部分代碼仍然是JsoupXpath的,這里非常感謝JsoupXpath,但是絕大部分代碼都被替換了,所以本身SipSoup不算依賴JsoupXpath(組件結(jié)構(gòu)幾乎還和JsoupXpath保持了一致)。 目前看來,SipSoup完全兼容JsoupXpath,因為它本身自JsoupXpath發(fā)展而來。關(guān)于JsoupXpath的相關(guān)資料,參考 JSoupXpath

          以下為改動點

          1. 函數(shù)重構(gòu),JsoupXpath使用反射加載一個類里面的靜態(tài)函數(shù),SipSoup則是使用接口實現(xiàn)的方式擴展

          2. 類掃描,默認函數(shù)注冊,是通過掃描器自動注冊,如果你需要擴展自己的函數(shù),可以將自己的函數(shù)實現(xiàn)放到com.virjar.sipsoup.function,就能夠自動注冊

          3. 軸函數(shù),SipSoup不光支持一般的謂語函數(shù)擴展,同時支持軸函數(shù),抽取函數(shù)擴展。而且允許函數(shù)帶參數(shù)

          4. css('cssQuery') css是SipSoup內(nèi)置的重要軸函數(shù),它可以將css查詢表達式傳遞給css軸,這是SipSoup一個大的突破,他比Xsoup更加容易的實現(xiàn)了css和xpath混合鏈式抽取

          5. 復(fù)雜謂語,目前來說,SipSoup對謂語的支持是我發(fā)現(xiàn)的最完善的,支持函數(shù)嵌套,表達式嵌套,括號嵌套,處理空格,轉(zhuǎn)義等問題。SipSoup的謂語模塊,是我花了整整一天寫出來的計算器

          6. 謂語數(shù)據(jù)類型擴展,在xpath語法中,我定義了數(shù)據(jù)類型分為: 字符串,數(shù)字,運算符,xpath,函數(shù),屬性取值動作,布爾類型,復(fù)合表達式 這幾種類型,其中除運算符以外的其他數(shù)據(jù)類型都是可以擴展或者卸載的。(boolean類型是開始設(shè)計的時候沒有的類型,然后通過這個機制注冊了boolean,后來又將其添加到了默認類型了)

          7. 運算符重載,運算符重載一般c++ 聽得挺多,含義就是可以通過重載運算符實現(xiàn)操作符的行為改寫。比如"+"加法操作,遇到數(shù)字執(zhí)行加法,遇到字符串執(zhí)行字符串鏈接,你可以重寫他,遇到數(shù)字轉(zhuǎn)化數(shù)字,失敗使用默認值等等

          8. 多xpath組合邏輯,可以實現(xiàn)多個xpath的多重與或計算,對應(yīng)集合實現(xiàn)交集,并集計算

          總之,SipSoup已經(jīng)是一個高度擴展的Xpath語法分析器,通過靈活的擴展以及Jsoup整合,成為了一個異常強大的xpath工具

          軟件主頁:http://git.oschina.net/virjar/sipsoup

          demo如下:

          1. 格式化輸出節(jié)點文本 allText allText()

          2. position使用,選取所有偶數(shù)節(jié)點 position

          3. 注冊新的函數(shù) RegisterNewFunctionTest.java

          4. 注冊新的操作符 運算符重載

          5. 福利,美女爬蟲 實際demo

          風(fēng)騷語法展示:

           <ul class="ad-thumb-list"> 
             <a href="www.java1234.com/test.jpg">這是一個混淆的圖片數(shù)據(jù)</a>
             <li> 
              <div class="inner"> 
               <a  /></a> 
              </div> </li> 
             <li> 
              <div class="inner"> 
               <a  /></a> 
              </div> </li> 
             <li> 
              <div class="inner"> 
               <a  /></a> 
              </div> </li> 
             <ul></ul>
            </ul>

          這個文本,需要提取所有偶數(shù)行的a標簽的圖片的鏈接信息,對應(yīng)xpath表達式可以這么寫

          //css('.ad-thumb-list .inner')::a[position(parent(2)) %2 =0]/@href 語法解釋

          1. css('.ad-thumb-list .inner'):: 這是css軸的運用,這個表達式定位到了所有的圖片數(shù)據(jù)(其中"<a href="www.java1234.com/test.jpg"\>這是一個混淆的圖片數(shù)據(jù)"將會被過濾)

          2. a[position(parent(2)) %2 =0] 這是復(fù)雜謂語的一個簡單應(yīng)用,首先a[xxx]定位到a標簽,然后使用parent函數(shù)得到他的爺爺節(jié)點,(parent函數(shù)可以帶參數(shù),必須是一個數(shù)字,2代表父親的父親,也就是得到了li標簽)

          3. 然后使用position函數(shù)得到這個li元素的position偏移,也就是他是第幾個li。

          4. 最后,讓他和2取模,如果結(jié)果為0,代表他就是偶數(shù)資源

          maven坐標

           <!-- xpath -->
           <dependency>
                <groupId>com.virjar</groupId>
                <artifactId>sipsoup</artifactId>
                <version>RELEASE</version>
          </dependency>

          具體文檔

          函數(shù)

          所有支持的函數(shù),可以通過如下demo得到 解析函數(shù)的demo

          軸函數(shù) :ancestor
          軸函數(shù) :ancestorOrSelf
          軸函數(shù) :cacheCss
          軸函數(shù) :child
          軸函數(shù) :css
          軸函數(shù) :descendant
          軸函數(shù) :descendantOrSelf
          軸函數(shù) :followingSibling
          軸函數(shù) :followingSiblingOne
          軸函數(shù) :parent
          軸函數(shù) :precedingSibling
          軸函數(shù) :precedingSiblingOne
          軸函數(shù) :self
          軸函數(shù) :sibling
          謂語過濾函數(shù) :|abs
          謂語過濾函數(shù) :|allText
          謂語過濾函數(shù) :|boolean
          謂語過濾函數(shù) :|concat
          謂語過濾函數(shù) :|contains
          謂語過濾函數(shù) :|false
          謂語過濾函數(shù) :|first
          謂語過濾函數(shù) :|hasClass
          謂語過濾函數(shù) :|last
          謂語過濾函數(shù) :|lower-case
          謂語過濾函數(shù) :|matches
          謂語過濾函數(shù) :|name
          謂語過濾函數(shù) :|not
          謂語過濾函數(shù) :|nullToDefault
          謂語過濾函數(shù) :|parent
          謂語過濾函數(shù) :|position
          謂語過濾函數(shù) :|root
          謂語過濾函數(shù) :|string
          謂語過濾函數(shù) :|string-length
          謂語過濾函數(shù) :|substring
          謂語過濾函數(shù) :|text
          謂語過濾函數(shù) :|toDouble
          謂語過濾函數(shù) :|toInt
          謂語過濾函數(shù) :|true
          謂語過濾函數(shù) :|try
          謂語過濾函數(shù) :|upper-case
          抽取函數(shù) :allText
          抽取函數(shù) :@
          抽取函數(shù) :html
          抽取函數(shù) :node
          抽取函數(shù) :num
          抽取函數(shù) :outerHtml
          抽取函數(shù) :self
          抽取函數(shù) :tag
          抽取函數(shù) :text

          軸函數(shù)

          軸函數(shù)是定義節(jié)點塞選域的函數(shù),在一個xpath表達式節(jié)點中,軸是可選的。但是如果存在軸,那么他的作用則是根據(jù)當(dāng)前的節(jié)點集產(chǎn)生新的一片候選節(jié)點集。 SipSoup的軸和標準Xpath的軸保持兼容,但是也有一個地方不一樣,就是SipSoup的軸允許帶有參數(shù),軸參數(shù)目前只支持字符串,可以支持多個字符串的參數(shù)。

          軸函數(shù)列表

          函數(shù)名稱 參數(shù) 作用
          ancestor 全部祖先節(jié)點 父親,爺爺 , 爺爺?shù)母赣H...
          ancestorOrSelf 全部祖先節(jié)點和自身節(jié)點
          cacheCss css query表達式 內(nèi)部實現(xiàn)路由至Jsoup的select,和css軸不一樣的是,cacheCss會對css規(guī)則進行緩存,在遇到大量同類型網(wǎng)頁的解析的時候,可能一個css規(guī)則被多次使用,緩存css能夠減少css規(guī)則編譯的消耗,提升性能
          child 直接子節(jié)點
          css css query表達式 內(nèi)部實現(xiàn)路由至Jsoup的select
          descendant 全部子代節(jié)點 兒子,孫子,孫子的兒子...
          descendantOrSelf 全部子代節(jié)點和自身
          following-sibling 節(jié)點后面的全部同胞節(jié)點following-sibling
          following-sibling-one 返回下一個同胞節(jié)點(擴展) 語法 following-sibling-one
          parent 父節(jié)點
          preceding-sibling 節(jié)點前面的全部同胞節(jié)點,preceding-sibling
          preceding-sibling-one 返回前一個同胞節(jié)點(擴展),語法 preceding-sibling-one
          self 自身
          sibling 全部同胞(擴展)

          抽取函數(shù)

          抽取函數(shù)用來對結(jié)果集進行轉(zhuǎn)換,他是一些簡單的數(shù)據(jù)抽取函數(shù),如提取所有文本,提取某個屬性等等,抽取函數(shù)目前不會太多。抽取結(jié)果可能為元素,也能為字符串。請注意,如果xpath節(jié)點中,存在抽取函數(shù),而且抽取函數(shù)返回類型為字符串,那么這個函數(shù)應(yīng)該是這個xpath節(jié)點鏈的末尾節(jié)點。因為每個抽取節(jié)點開始的時候,將會執(zhí)行過濾,只會將element作為下一輪抽取的輸入。

          軸函數(shù)列表(哪位大神能幫我調(diào)整以下表格布局,真丑,我不喜歡)

          函數(shù)名稱 參數(shù) 作用
          allText 遞歸獲取節(jié)點內(nèi)全部的純文本,將block的html元素轉(zhuǎn)化為換行符,能夠保持原有的html的段落結(jié)構(gòu),但是不能保持布局結(jié)構(gòu)
          @ 抽取當(dāng)前節(jié)點的某個屬性,數(shù)據(jù)內(nèi)部函數(shù),外界不可直接調(diào)用,原因是函數(shù)語法識別器不會識別"@"函數(shù),但是"@"操作符本身內(nèi)部是轉(zhuǎn)化抽取函數(shù)了
          html 獲取全部節(jié)點的內(nèi)部的html
          node 獲取全部節(jié)點的html
          num 抽取節(jié)點自有文本中全部數(shù)字
          outerHtml 獲取全部節(jié)點的 包含節(jié)點本身在內(nèi)的全部html
          self 放棄抽取,保留自身。xpath默認會對當(dāng)前節(jié)點的子節(jié)點進行操作,而有些時候軸函數(shù)定位到的節(jié)點就是需要的數(shù)據(jù)了,所以不需要在使用抽取函數(shù)計算新節(jié)點了,主要用在tag函數(shù)不能解決的場景下
          tag tagName 內(nèi)部函數(shù),xpath 語法中的tag字段,默認路由到此函數(shù)處理//div[@class] 這里的div在運行時會轉(zhuǎn)化為 //tag('div')[@'class']這兩個表達式等價,但是第一個表達式才是xpath常規(guī)思路,而且對SipSoup這兩個表達式性能完全一樣
          text 只獲取節(jié)點自身的子文本

          過濾函數(shù)

          過濾函數(shù)用在謂語中,過濾函數(shù)非常強大,因為它能夠遞歸的使用函數(shù),配合操作符,實現(xiàn)復(fù)雜的表達式計算,

          過濾函數(shù)列表

          函數(shù)名稱 參數(shù) 作用
          abs 數(shù)字,可以是整數(shù)或者小數(shù) 返回參數(shù)的絕對值。例子:abs(-3.14) 結(jié)果:3.14
          allText 獲取元素下面的全部文本
          boolean 數(shù)字,boolean,字符串 返回數(shù)字、字符串的布爾值。如果沒有參數(shù),則默認返回false,如果本身是boolean,返回boolean,如果是字符串,嘗試轉(zhuǎn)化為boolean,如果是整數(shù),非零為真。其他類型的數(shù)字,大于零為真。剩余場景全部返回false
          concat 多個參數(shù),可以為任意類型 返回字符串的拼接,例子:concat('XPath ','is ','FUN!') 結(jié)果:'XPath is FUN!',如果非字符串,則轉(zhuǎn)化為字符串后執(zhí)行字符串拼接
          contains 兩個參數(shù),左右都為字符串,測試左側(cè)字符串中是否包含右側(cè)字符串 如果 string1 包含 string2,則返回 true,否則返回 false
          false 返回布爾值 false
          first 判斷一個元素是不是同名同胞中的第一個,可以使用position函數(shù)代替,遷移自JSoupXpath的函數(shù)
          hasClass 字符串,為css的class樣式名稱 css規(guī)則的className,實際上會調(diào)用Jsoup的hasClass方法(Jsoup本身的抽取器也是調(diào)用這個方法的)
          last 判斷一個元素是不是最后一個同名同胞中的
          lower-case 一個參數(shù),類型為字符串 轉(zhuǎn)化字符串為大寫
          matches 兩個參數(shù),類型為字符串 如果 string 參數(shù)匹配指定的模式,則返回 true,否則返回 false,例子:matches("Merano", "ran") 結(jié)果:true
          name 獲取當(dāng)前節(jié)點的節(jié)點名稱
          not 和boolean的參數(shù)相同 首先通過 boolean() 函數(shù)把參數(shù)還原為一個布爾值。如果該布爾值為 false,則返回 true,否則返回 true
          nullToDefault 兩個參數(shù),任意類型 如果第一個參數(shù)的值為null,則第三個參數(shù)作為本函數(shù)的返回值,否則第一個參數(shù)為本函數(shù)的返回值
          parent 一個或者零個參數(shù),均為正整數(shù)類型 如果沒有參數(shù),則獲取當(dāng)前節(jié)點的父親節(jié)點,返回值為element類型,如果傳遞了參數(shù),則指定n代祖先對應(yīng)節(jié)點
          position 一個或者零個參數(shù),為節(jié)點類型 如果沒有傳遞參數(shù),或者第一個參數(shù)計算結(jié)果為null,則返回當(dāng)前節(jié)點在兄弟節(jié)點中的位置。否則返回傳入的節(jié)點相對于傳入節(jié)點兄弟節(jié)點的位置
          root 返回當(dāng)前節(jié)點的根節(jié)點,一般是document節(jié)點
          string 一個參數(shù),任意類型 返回參數(shù)的字符串值。參數(shù)可以是數(shù)字、邏輯值
          string-length 一個參數(shù),字符串類型 返回字符的長度
          substring 兩個或者參數(shù) 第一個參數(shù)為字符串類型,第二個參數(shù)為數(shù)字,第三個參數(shù)如果存在,也必須是數(shù)字類型。本函數(shù)返回字符串對應(yīng)子串。第二個參數(shù)為起始偏移,如果第三個參數(shù)存在,則第三個參數(shù)為結(jié)尾偏移,否則結(jié)尾為字符串末尾
          text 獲取元素自己的子文本
          toDouble 一個或者兩個參數(shù),第一個需要是數(shù)字,第二個如果存在,則需要是double類型 將一個字符串轉(zhuǎn)化為double,如果轉(zhuǎn)化失敗,嘗試使用默認值返回
          toInt 個或者兩個參數(shù),第一個需要是數(shù)字,第二個如果存在,則需要是int類型 將一個字符串轉(zhuǎn)化為int,如果轉(zhuǎn)化失敗,嘗試使用默認值返回
          true 返回布爾值 true
          try 異常處理,0,1,2個參數(shù) 如果參數(shù)為空,返回true,如果第一個參數(shù)對應(yīng)語法節(jié)點無異常執(zhí)行,則返回第一個參數(shù)。否則返回第二個參數(shù)(此時如果第二個參數(shù)不存在,返回false)
          upper-case 一個參數(shù),類型為字符串 轉(zhuǎn)化字符串為小寫

          操作符

          目前操作符相關(guān),遷移自JSoupXpath其運算規(guī)則和JSoupXpath保持一致,SipSoup支持多個運算符組合,所以涉及操作符優(yōu)先級問題(除非非常常見的用法,一般建議使用括號手動確定優(yōu)先級) 操作符和對應(yīng)優(yōu)先級如下表,其中優(yōu)先級高越優(yōu)先的到計算,如果操作符優(yōu)先級相同,則按照從左往右的順序計算。

          各運算符優(yōu)先級定義
          
          +   :20   加法運算
          -   :20   減法運算
          *   :30   乘法運算
          /   :30   除法運算
          %   :30   取模運算
          &&  :0    邏輯且運算
          ||  :0    邏輯或運算
          and :0    邏輯且運算,等價于&&
          or  :0    邏輯或運算,等價于||
          =   :10   相等判斷,邏輯運算
          >   :10   大于,邏輯運算
          <   :10   小于,邏輯運算
          >=  :10   大于等于,邏輯運算
          <=  :10   小于等于,邏輯運算
          *=  :10   包含,測試表達式左側(cè)數(shù)據(jù)是否包含表達式右側(cè)數(shù)據(jù),僅適用于字符串,邏輯運算
          $=  :10   以xxx結(jié)尾,測試左側(cè)數(shù)據(jù)是否以表達式右側(cè)數(shù)據(jù)結(jié)尾,僅適用于字符串,邏輯運算
          ^=  :10   以xxx開始,測試左側(cè)數(shù)據(jù)是否以表達式右側(cè)數(shù)據(jù)開始,僅適用于字符串,邏輯運算
          !=  :10   不等于,和"="作用相反,邏輯運算
          ~=  :10   模式匹配,測試左側(cè)數(shù)據(jù)是否符合右側(cè)字符串代表的正則表達式模式,僅適用于字符串,邏輯運算
          !~  :10   不匹配,與"~="相反,如果左側(cè)數(shù)據(jù)不匹配右側(cè)字符串代表的正則表達式,則返回true

          操作符類型

          操作符計算涉及到數(shù)據(jù)類型升級問題,如一個整形數(shù)據(jù)和一個長整形計算,將會轉(zhuǎn)化為長整形。SipSoup默認支持較好的數(shù)字類型有:int,long,double(float按double處理),BigDecimal,并且會根據(jù)一般的慣例處理轉(zhuǎn)型計算的問題

          特別說明,對于+有兩個動作,如果遇到數(shù)字,則執(zhí)行數(shù)字加法,如果遇到字符串,則執(zhí)行字符串鏈接。如果你覺得不應(yīng)該有這個表現(xiàn),可以通過重寫操作符的方式修改

          高級用法

          1. 注冊或重寫新的函數(shù) RegisterNewFunctionTest.java

          2. 注冊或重寫新的操作符 運算符重載

          3. 注冊新的數(shù)據(jù)類型 TokenAnalysisRegistry.java 這里不展示細節(jié)了,如果你需要這個功能了,那么你對SipSoup的源代碼應(yīng)該足夠了解,應(yīng)該可以獨立駕馭這個類,并根據(jù)SipSoup定義的規(guī)范識識別新數(shù)據(jù)類型的格式,以及消費轉(zhuǎn)化為特性計算節(jié)點模型

          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩国产精品一级毛片在线 | 东北操逼网 | 日韩1234 | 国产欧美色图 | 91色色色 |