xpath

xpath全稱XML Path language, 即xml路徑語言,最初用來搜尋xml文檔的,一樣適用於html文檔的搜尋html

經常使用規則:node

 nodename 選取此節點的全部子節點
/ 從當前節點選取直接子節點
// 從當前節點選取子孫節點
. 選取當前節點
.. 選取當前借點的父節點
@ 選取屬性
from lxml import etree
text = '''
<dd>
                        <i class="board-index board-index-1">1</i>
    <a href="/films/1203" title="霸王別姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
      <img src="//ms0.meituan.net/mywww/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
      <img data-src="http://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王別姬" class="board-img" />
    </a>
    <div class="board-item-main">
      <div class="board-item-content">
              <div class="movie-item-info">
        <p class="name"><a href="/films/1203" title="霸王別姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王別姬</a></p>
        <p class="star">
                主演:張國榮,張豐毅,鞏俐
        </p>
<p class="releasetime">上映時間:1993-01-01(中國香港)</p>    </div>
    <div class="movie-item-number score-num">
<p class="score"><i class="integer">9.</i><i class="fraction">6</i></p>
    </div>

      </div>
    </div>
'''
html = etree.HTML(text)
result = etree.tostring(html)
print(result.decode('utf-8'))

這裏首先導入lxml庫的etree模塊,而後聲明瞭一段html文本,使用html類進行初始化,這樣就成功的構造了一個xpath解析對象,須要注意的是,html文本中最後一個節點dd是沒有閉合的,可是etree模塊自動修正了html文本函數

調用tostring()方法便可輸出修正後的html代碼post

 

也能夠直接讀取文本文件進行解析spa

html = etree.aprse('./xpath.html',etree.HTMLParser())
result = etree.tostring(html)
print(result.decode('utf-8'))

此次得輸出結果略有不一樣,多了一個DOCTYPE的聲明,可是對解析結果沒有任何影響.net

 

全部節點3d

咱們通常使用//開頭的xpath規則來選取全部符合要求的節點code

html = etree.parse('./xpath.html',etree.HTMLParser())
result = html.xpath('//*')
print(result)

使用*號來匹配全部節點,也就是整個html文本中的全部節點都會被獲取,返回形式是一個列表,每一個元素是Element類型的,其後跟了節點的名稱,如html,div,ul等xml

選取全部的a節點,可使用//,後面加上節點名稱就行htm

html = etree.parse('./xpath.html',etree.HTMLParser())
result = html.xpath('//a')
print(result)
#[<Element a at 0x108f47448>, <Element a at 0x108f47488>]

print(result[0])
#<Element a at 0x108721488>

可容易看到結果是一個列表形式,每個元素都是一個Element對象,若是要提取其中一個對象能夠直接中括號加索引

 

屬性匹配

//li[@class='item']  #獲取全部class爲item的li節點

屬性獲取

咱們知道text()獲取節點內部文本,那麼節點屬性該怎樣獲取呢,其實仍是用@符號就能夠了

//li/a/@href  #查找全部的li節點的直接子節點的href屬性值

 

屬性多值匹配

有些時候某些節點的屬性可能有多個值

<li class="li li-first" name="item"><a href="link.html">first</a></li>

這裏的li節點的class 屬性就有兩個值li和li-first,若是還用以前的屬性匹配獲取,就沒法匹配了

須要使用contains()函數

//li[contains(@class,'li')]/a/text()

經過contains()方法,第一個參數傳入屬性名稱,第二個參數傳入屬性值,只要此屬性中包含傳入的屬性值,就能夠完成匹配

 

多屬性匹配

還會遇到一種狀況,就是根據多個屬性肯定一個節點,這時就須要匹配多個屬性,使用運算符and來鏈接

//li[contains(@class,"li") and @name="item"]/a/text()

這裏的and實際上是xpath中的運算符,還有以下

or
and
mod 取餘
| 返回擁有兩邊元素節點集
+  
-  
*  
div 除法
=  

!=

 
<  
<=  
>  
>=  

 

按序選擇

有時候咱們選擇屬性時,匹配到了多個節點,可是咱們只想要其中的某個節點,

//li[1]/a/text() #選取第一個節點,中括號傳入1便可,序號是以1開頭的

//li[last()]/a/text() #選取最後一個節點

//li[position()<3]/a/text #選取序號小於3的,也就是選擇1,2

//li[last()-2]/a/text() #選擇倒數第三個節點,由於last()是最後一個,因此last()-2是倒數第三個

 

節點軸選擇

//li[1]/ancestor::*  #獲取全部祖先節點

//li[1]/ancestor::div  #獲取指定祖先節點div

//li[1]/attribute::*  #獲取節點的全部屬性

//li[1]/child::a[@href="like.html"] #獲取全部直接子節點,條件:href屬性爲like.html的a節點

//li[1]/descendant::span  #獲取全部子孫節點:條件:返回只包含span節點

//li[1]/following::*[2]    #當前節點以後的全部節點,但加了索引匹配,只選擇第二個後續節點

//li[1]following-sibling::*  #返回節點以後的同級節點
相關文章
相關標籤/搜索