目錄html
@(這裏寫自定義目錄標題)node
XPath(全稱XML Path Languang),即XML路徑語言,是一種在XML文檔中查找信息的語言。適用於XML和HTML文檔的搜索。
優勢:提供了很是簡潔明瞭的路徑選擇表達式。還提供了超過100個內建函數,能夠匹配大部分的節點。
官網:https://www.w3.org/TR/xpath/
準備工做:須要安裝lxml庫。
python
表達式 | 功能 |
---|---|
nodename | 選取此節點的全部子節點 |
/ | 從當前節點選取直接子節點 |
// | 從當前節點選取直接子孫節點 |
. | 選取當前節點 |
.. | 選取當前節點的父節點 |
@ | 選取屬性 |
etree是lxml庫中的函數,能夠自動修正HTML文本。下面是兩種導入方法:
直接讀取網頁代碼進行解析:函數
from lxml import etree text = ''' HTML文本 ''' # 將HTML文本轉化爲能夠用etree解析的對象, html = etree.HTML(text) # 結果是bytes類型,若是須要文本輸出,則須要用decode()轉碼爲Unicode編碼
讀取文本文件進行解析(這裏既會自動修正文件,又會補充DOCTYPE聲明):工具
from lxml import etree html = etree.parse('文本文件路徑/文本文件名字.html',etree.HTMLParse()) # 結果是bytes類型,若是須要文本輸出,則須要用decode()轉碼爲Unicode編碼
用tostring()方法便可輸出修正後的HTML代碼。
編碼
通常用//開頭的XPath規則,就會選擇從當前節點開始的全部子孫節點,也就是全部節點。因此要匹配全部的節點代碼以下:code
a = html.xpath('//*') # 選取全部的節點 b = html.xpath('//a') # 選取全部的a節點,是一個例子
這裏的a和b,也就是xpath方法的返回值是一個列表,每一個元素是Element類型,後面跟着節點的名稱,是一個可迭代對象。要取出某一個對象,就須要用處理列表的方法進行。xml
選取子節點只須要在後面加上/節點名稱(選擇直接子節點,也就是與其相鄰的第一個子節點),若是直接子節點沒有就會報錯,或者//節點名稱(選擇全部子孫節點),例子以下:htm
c = html.xpath('//li/a') # 選取li節點的直接a子節點 d = html.xpath('//li//a') # 選取li節點的全部a子節點
獲取某個節點的父節點有兩個方法,一個是用..,另外一個是用parent::。
同理,若是沒有父節點,就會報錯,例子以下:對象
e = html.xpath('//li/../a') # 選取li節點的父節點下的a節點 f = html.xpath('//li/parent::/a') # 選取li節點的父節點下的直接a節點 g = html.xpath('//li/parent::*/a') # 選取li節點的父節點下的全部a節點
在選取節點的時候,能夠用@符號進行屬性過濾,用[@屬性名="屬性值"]進行實現,例子以下:
s = html.xpath('//li[@class="ming"]') # 選取屬性值class="ming"的全部li節點
要注意的是裏面的括號和外面的括號儘可能一個用雙引號,一個用單引號。
咱們用Xpath中的text()方法便可獲取節點中的文本。要注意的是獲取到的數據可能包括換行符'\n'。
要是屬性有多個值的話,用上面的方法就沒法匹配了。須要用到contains()函數,包含兩個參數,即@屬性名和屬性值,例子以下:
# 源代碼中爲<li class="ming1 ming2"> s1 = html.xpath('//li[contains(@class,"ming1")]') # 選取屬性值class="ming1"的全部li節點 s2 = html.xpath('//li[contains(@class,"ming2")]') # 選取屬性值class="ming2"的全部li節點
屬性獲取直接用@獲取便可,例子以下:
s = html.xpath('//li/a/@href]') # 獲取全部li節點下的直接a子節點的href屬性
有時候須要根據多個屬性值肯定一個節點,就須要同時匹配多個屬性。要用and進行鏈接,能夠把contains(@屬性名,"屬性名")和@屬性名="屬性值"混合使用,例子以下:
# 選取全部屬性值class="a"和_target="ming"的li節點下的全部a節點的href屬性 two_s = html.xpath('//li[contains(@class,"a") and @_target="ming"]//a/@href')
有時候選擇到的某些屬性可能同時匹配了多個節點,可是要想獲得其中的某一個節點,該如何獲取呢?能夠用中括號傳入索引的方法獲取特定次序的節點。下面是一些經常使用方法的總結:
方法 | 功能 |
---|---|
[n] | 選取第n個節點,序號是以1開頭的 |
[last()] | 選取最後一個節點 |
[position() < n] | 選取位置小於n的節點,這裏能夠用算術運算符進行選擇 |
[last() - n] | 選取倒數第n+1個節點,因爲last()是倒數第一個,則last() - n就是倒數第n+1個 |
因爲網頁代碼是一個DOM樹,所以能夠用相對的位置進行選擇節點的子節點,兄弟節點,父節點或者祖先節點等。python的節點軸選擇經常使用的以下:
節點軸 | 選擇節點 |
---|---|
ancestor:: * | 獲取全部祖先節點 |
ancestor::條件 | 獲取指定條件的祖先節點 |
attribute:: * | 獲取節點的全部屬性 |
attribute::屬性名 | 獲取節點的指定屬性 |
child:: * | 獲取全部子節點 |
child::條件 | 獲取指定條件的子節點 |
descendent:: * | 獲取全部的子孫節點 |
descendent::條件 | 獲取指定條件的子孫節點 |
following:: * | 獲取當前節點以後的全部節點 |
following:: *[n] | 獲取當前節點以後的第n個節點 |
following-sibing:: * | 獲取當前節點以後的全部同級節點 |
following-sibing::條件 | 獲取當前節點以後指定條件的全部同級節點 |
用F12打開開發者工具,按才Copy->Copy Xpath就能夠把該段代碼的XPath路徑代碼複製下來,很方便。