Python爬蟲利器三之Xpath語法與lxml庫的用法


前言

前面我們介紹了 BeautifulSoup 的用法,這個已經是非常強大的庫了,不過還有一些比較流行的解析庫,例如 lxml,使用的是 Xpath 語法,同樣是效率比較高的解析方法。如果大家對 BeautifulSoup 使用不太習慣的話,可以嘗試下 Xpath。

參考來源

lxml用法源自 lxml python 官方文檔,更多內容請直接參閱官方文檔,本文對其進行翻譯與整理。

lxml

XPath語法參考 w3school

w3school

安裝

 pypi下載地址:https://pypi.python.org/pypi/lxml/3.4.2#downloads

利用 pip 安裝即可

XPath語法

XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。XPath 是 W3C XSLT 標准的主要元素,並且 XQuery 和 XPointer 都構建於 XPath 表達之上。

節點關系

(1)父(Parent)

每個元素以及屬性都有一個父。

在下面的例子中,book 元素是 title、author、year 以及 price 元素的父:

(2)子(Children)

元素節點可有零個、一個或多個子。

在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:

(3)同胞(Sibling)

擁有相同的父的節點

在下面的例子中,title、author、year 以及 price 元素都是同胞:

(4)先輩(Ancestor)

某節點的父、父的父,等等。

在下面的例子中,title 元素的先輩是 book 元素和 bookstore 元素:

(5)后代(Descendant)

某個節點的子,子的子,等等。

在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:

 

選取節點

XPath 使用路徑表達式在 XML 文檔中選取節點。節點是通過沿着路徑或者 step 來選取的。

下面列出了最有用的路徑表達式:

表達式 描述
nodename 選取此節點的所有子節點。
/ 從根節點選取。
// 從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。
. 選取當前節點。
.. 選取當前節點的父節點。
@ 選取屬性。

實例

在下面的表格中,我們已列出了一些路徑表達式以及表達式的結果:

路徑表達式 結果
bookstore 選取 bookstore 元素的所有子節點。
/bookstore 選取根元素 bookstore。注釋:假如路徑起始於正斜杠( / ),則此路徑始終代表到某元素的絕對路徑!
bookstore/book 選取屬於 bookstore 的子元素的所有 book 元素。
//book 選取所有 book 子元素,而不管它們在文檔中的位置。
bookstore//book 選擇屬於 bookstore 元素的后代的所有 book 元素,而不管它們位於 bookstore 之下的什么位置。
//@lang 選取名為 lang 的所有屬性。

謂語(Predicates)

謂語用來查找某個特定的節點或者包含某個指定的值的節點。

謂語被嵌在方括號中。

實例

在下面的表格中,我們列出了帶有謂語的一些路徑表達式,以及表達式的結果:

路徑表達式 結果
/bookstore/book[1] 選取屬於 bookstore 子元素的第一個 book 元素。
/bookstore/book[last()] 選取屬於 bookstore 子元素的最后一個 book 元素。
/bookstore/book[last()-1] 選取屬於 bookstore 子元素的倒數第二個 book 元素。
/bookstore/book[position()<3] 選取最前面的兩個屬於 bookstore 元素的子元素的 book 元素。
//title[@lang] 選取所有擁有名為 lang 的屬性的 title 元素。
//title[@lang=’eng’] 選取所有 title 元素,且這些元素擁有值為 eng 的 lang 屬性。
/bookstore/book[price>35.00] 選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大於 35.00。
/bookstore/book[price>35.00]/title 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大於 35.00。

選取未知節點

XPath 通配符可用來選取未知的 XML 元素。

通配符 描述
* 匹配任何元素節點。
@* 匹配任何屬性節點。
node() 匹配任何類型的節點。

實例

在下面的表格中,我們列出了一些路徑表達式,以及這些表達式的結果:

路徑表達式 結果
/bookstore/* 選取 bookstore 元素的所有子元素。
//* 選取文檔中的所有元素。
//title[@*] 選取所有帶有屬性的 title 元素。

選取若干路徑

通過在路徑表達式中使用“|”運算符,您可以選取若干個路徑。

實例

在下面的表格中,我們列出了一些路徑表達式,以及這些表達式的結果:

路徑表達式 結果
//book/title | //book/price 選取 book 元素的所有 title 和 price 元素。
//title | //price 選取文檔中的所有 title 和 price 元素。
/bookstore/book/title | //price 選取屬於 bookstore 元素的 book 元素的所有 title 元素,以及文檔中所有的 price 元素。

XPath 運算符

下面列出了可用在 XPath 表達式中的運算符:

運算符 描述 實例 返回值
| 計算兩個節點集 //book | //cd 返回所有擁有 book 和 cd 元素的節點集
+ 加法 6 + 4 10
減法 6 – 4 2
* 乘法 6 * 4 24
div 除法 8 div 4 2
= 等於 price=9.80 如果 price 是 9.80,則返回 true。如果 price 是 9.90,則返回 false。
!= 不等於 price!=9.80 如果 price 是 9.90,則返回 true。如果 price 是 9.80,則返回 false。
< 小於 price<9.80 如果 price 是 9.00,則返回 true。如果 price 是 9.90,則返回 false。
<= 小於或等於 price<=9.80 如果 price 是 9.00,則返回 true。如果 price 是 9.90,則返回 false。
> 大於 price>9.80 如果 price 是 9.90,則返回 true。如果 price 是 9.80,則返回 false。
>= 大於或等於 price>=9.80 如果 price 是 9.90,則返回 true。如果 price 是 9.70,則返回 false。
or price=9.80 or price=9.70 如果 price 是 9.80,則返回 true。如果 price 是 9.50,則返回 false。
and price>9.00 and price<9.90 如果 price 是 9.80,則返回 true。如果 price 是 8.50,則返回 false。
mod 計算除法的余數 5 mod 2 1

lxml用法

初步使用

首先我們利用它來解析 HTML 代碼,先來一個小例子來感受一下它的基本用法。

首先我們使用 lxml 的 etree 庫,然后利用 etree.HTML 初始化,然后我們將其打印出來。

其中,這里體現了 lxml 的一個非常實用的功能就是自動修正 html 代碼,大家應該注意到了,最后一個 li 標簽,其實我把尾標簽刪掉了,是不閉合的。不過,lxml 因為繼承了 libxml2 的特性,具有自動修正 HTML 代碼的功能。

所以輸出結果是這樣的

不僅補全了 li 標簽,還添加了 body,html 標簽。

文件讀取

除了直接讀取字符串,還支持從文件讀取內容。比如我們新建一個文件叫做 hello.html,內容為

利用 parse 方法來讀取文件。

同樣可以得到相同的結果。

XPath實例測試

依然以上一段程序為例

(1)獲取所有的 <li> 標簽

運行結果

可見,etree.parse 的類型是 ElementTree,通過調用 xpath 以后,得到了一個列表,包含了 5 個 <li> 元素,每個元素都是 Element 類型

(2)獲取 <li> 標簽的所有 class

運行結果

(3)獲取 <li> 標簽下 href 為 link1.html 的 <a> 標簽

運行結果

(4)獲取 <li> 標簽下的所有 <span> 標簽

注意這么寫是不對的

因為 / 是用來獲取子元素的,而 <span> 並不是 <li> 的子元素,所以,要用雙斜杠

運行結果

(5)獲取 <li> 標簽下的所有 class,不包括 <li>

運行結果

(6)獲取最后一個 <li> 的 <a> 的 href

運行結果

(7)獲取倒數第二個元素的內容

運行結果

(8)獲取 class 為 bold 的標簽名

運行結果

通過以上實例的練習,相信大家對 XPath 的基本用法有了基本的了解。也可以利用 text 方法來獲取元素的內容。

大家多加練習!

結語

XPath 是一個非常好用的解析方法,同時也作為爬蟲學習的基礎,在后面的 selenium 以及 scrapy 框架中都會涉及到這部分知識,希望大家可以把它的語法掌握清楚,為后面的深入研究做好鋪墊。

轉載:靜覓 » Python爬蟲利器三之Xpath語法與lxml庫的用法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM