HTML文檔解析之Xpath(附 xpath helper工具)

一. 引入

XPath,全稱XML Path Language,即XML路徑語言,它是一門在XML文檔中
查找信息地語言。它最初是用來搜尋XML文檔的,而XML文檔與HTML文檔關係緊密,Xpath同樣適用於HTML文檔的搜索。

二. 安裝

pip install lxml

三. 快速開始

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">It's a good story</p>
<p>
<!--Hey, buddy. Want to buy a used parser?-->
</p>
"""
from lxml import etree
html = etree.HTML(html_doc)
result = etree.tostring(html)
print(result.decode('utf-8'))

  • 這裏首先導入 lxml庫的etree模塊,然後聲明瞭一段HTML文本,調用HTML類進行初始化,這樣就構成了一個XPath解析對象。這樣需要注意的是,HTML文本中 html 和 body節點是沒有閉合的,但etree模塊可以自動修正HTML文本。 這裏的 tostring()方法即可輸出修正後的HTML代碼,但是結果是bytes類型。這裏利用decode()方法轉化成str類型,結果如下:

  • 兩種使用方式:
  1. 本地文件:
			tree = etree.parse('文件名')
			ret =tree.xpath(路徑表達式)
  1. 網頁字符串:
		tree = etree.HTML('網頁字符串')
		ret =tree.xpath(路徑表達式)

四. Xpath 常用規則

五. 獲取節點

  • 獲取所有節點,我們一般會用 // 開頭的 XPath規則來獲取所有符合要求的節點。如下圖所示:


這裏使用 * 代表所有節點,也就是整個HTML文檔中的所有節點都會被獲取。可以看到,返回形式是一個列表,每個元素是Element類型,其後跟了節點的名稱,如 html、body、p等,所有節點都包含在列表中了。

  • 選取指定節點名稱,如果想獲得所有的 p 節點,示例如下:

  • 獲取子節點,我們通過 / 或 // 即可查找元素的子節點或子孫節點。假如現在想選擇 p節點的所有直接的a子節點,可以這樣實現:

    這裏我們通過追加 /a 即選擇了所有p節點的所有直接a節點。因爲 //p 用於選中所有p節點,/a 用於選中p節點的所有直接子節點,二者結合在一起獲取所有p節點的所有直接a節點。

    但是如果這裏用了 //body/a,就無法獲取到任何結果了。因爲 / 用於獲取直接子節點,而在 body節點下並沒有直接的 a 節點,只有 p 節點和 dt 節點,所以無法獲取任何匹配結果,代碼如下:

    因此,我們要注意 / 和 // 的區別,其中 / 用於獲取直接子節點,// 用於獲取子孫節點

  • 獲取父節點,我們知道通過連續的 / 或 //可以查找 子節點或子孫節點,那麼假如我們知道子節點,怎樣來查找父節點呢?可以使用 ..

    比如,現在首先選中 id 屬性爲 link1的a節點,然後在獲取其父節點,然後再取其 class屬性,相關代碼如下:

  • 屬性匹配,在選取的時候,我們還可以用 @ 符號進行屬性過濾。比如,這裏如果要選取 class 屬性爲 title 的 p 節點,可以這樣實現:


這裏我們通過假如 [@class=“title”],限制了節點的class屬性爲 title,而HTML文本中符合條件的p節點只有一個,即上圖所返回的結果。

  • 文本獲取,我們用XPath中的 text()方法獲取節點中的文本,接下來嘗試獲取 所有 p 節點的文本,代碼如下:

    另一種,獲得方法,代碼如下:

    p.text 方法 獲得到的是 p節點 直接子節點中的文本,第一個 p 節點中的直接子節點並沒有文本內容,所以返回爲 None

  • 屬性獲取,我們知道可以使用 text() 方法獲取節點內部文本,那麼節點屬性該怎樣獲取呢?其實還是 用 @符號就可以。比如,我們想獲取所有 a 節點的 href 屬性,代碼如下:

    這裏我們通過 @href即可獲取節點的href屬性。注意,此處和屬性匹配的方法不同,屬性匹配是中括號加屬性名和值來限定某個屬性,如 [@href=“story”],而此處的@href指的是獲取節點的某個屬性,二者要注意區分。

  • 屬性多值匹配,有時候,某些節點的某個屬性可能有多個值,例如,節點 dl,class屬性有兩個值 li 和 li-first,此時需要使用 contains() 函數進行匹配,運行結果如下:

  • 多屬性匹配,還可能遇到這種情況,那就是根據多個屬性來確定一個節點,這時就需要同時匹配多個屬性。此時可以使用運算符 and 來連接,如下:

在這裏插入圖片描述

這裏的 and 其實是 XPath中的運算符。另外,還有很多運算符,如 or mod 等,在此總結如下表所示:

六. chrome插件XPath Helper 工具 安裝 與 使用

  • 下載,由於目前 谷歌商店 沒有 FQ 是訪問不了的,這裏,我將已經下載好的,打包放在網盤中,供大家下載。

    鏈接:https://pan.baidu.com/s/13cnVKhBQeM8Tv2vAEmdiXA
    提取碼:n8bj

  • 安裝方法:

    下載到本地,打開 chrome瀏覽器,進入設置,點擊擴展程序,將下載好的 .crx後綴文件拖入擴展程序即可。

  • 使用方法:

    打開網頁後,快捷鍵 ctrl + shift + x 來使用插件。 結果如下:


可以在 query中寫 XPath 路徑表達式,進行測試。當然,還有一種方法,直接複製 瀏覽器中某個節點的XPath 路徑表達式:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章