XPath 是一種用于尋址 XML 文檔部分的語(yǔ)言。它在 XSLT 中使用并且是 XQuery 的子集。這個(gè)庫(kù)也可用于大多數(shù)其他編程語(yǔ)言。
在我前面的幾十篇文章,寫了上百萬(wàn)字把python的所有基礎(chǔ)已經(jīng)講得很明白了,不管你是不是小白,跟著學(xué)都能學(xué)會(huì),同時(shí)在我的粉絲群,我還會(huì)對(duì)教程中的問(wèn)題進(jìn)行答疑,所以包教包會(huì)的口號(hào),我從來(lái)不是吹的。
這里是我的基礎(chǔ)教程專欄:python全棧基礎(chǔ)詳細(xì)教程專欄系列
當(dāng)然,如果你對(duì)qq機(jī)器人制作感興趣請(qǐng)查看專欄:qq機(jī)器人制作詳細(xì)教程專欄
這兩個(gè)專欄,我為什么放在一起?第一個(gè)專欄是基礎(chǔ)教程,第二個(gè)專欄是進(jìn)階,所以你在不會(huì)基礎(chǔ)之前,請(qǐng)不要冒然學(xué)習(xí)機(jī)器人制作。
說(shuō)了半天,我還沒(méi)說(shuō)為什么寫這一篇的原因,前面的基礎(chǔ)我已經(jīng)差不多寫完了,基礎(chǔ)不會(huì)的自己去看我專欄,上百萬(wàn)字寫基礎(chǔ),我已經(jīng)很用心教大家了。基礎(chǔ)過(guò)后,我們即將開始學(xué)爬蟲,因此xpath你不得不掌握。認(rèn)真跟著我學(xué),多看幾天就會(huì)了。
其它專欄,看你自己個(gè)人興趣,這五個(gè)專欄我是主打,并是我強(qiáng)烈推薦。
有任何問(wèn)題可以粉絲群?jiǎn)栁遥?/p>
如果有一段html如下:
<html> <body> <a>link</a> <div class="container" id="divone"> <p class="common" id="enclosedone">Element One</p> <p class="common" id="enclosedtwo">Element Two</p> </div> </body></html>
在整個(gè)頁(yè)面中查找具有特定 id 的元素:
//*[@id="divone"] # 返回 在特定路徑中查找具有特定 id 的元素:
/html/body/div/p[@id="enclosedone"] # 返回 <p class="common" id="enclosedone">Element One</p>
選擇具有特定 id 和 class 的元素:
//p[@id="enclosedone" and @class="common"] #返回 Element One
選擇特定元素的文本:
//*[@id="enclosedone"]/text() # 返回 Element One
2.2 常見XML操作
比如有如下xml:
<r> <e a="1"/> <f a="2" b="1">Text 1</f> <f/> <g> <i c="2">Text 2</i> Text 3 <j>Text 4</j> </g></r>
2.2.1 選擇一個(gè)元素
用xpath
/r/e
將選擇此元素:
<e a="1"/>
2.2.2 選擇文字
用xpath:
/r/f/text()
將選擇具有此字符串值的文本節(jié)點(diǎn):
"Text 1"
而這個(gè) XPath:
string(/r/f)
返回同樣是:
"Text 1"
2.3 瀏覽器使用xpath調(diào)試
步驟如下:
- 按F12進(jìn)入控制臺(tái)
- 按ctrl+F進(jìn)入搜索框
- 將自己寫的xpath輸入進(jìn)去,回車看看能不能匹配到
2.3.1演示案例一
以我自己的主頁(yè)網(wǎng)址為例:
https://blog.csdn.net/weixin_46211269?spm=1000.2115.3001.5343
分析:
鎖定定位為:
user-profile-statistics-num
則xpath寫為:
//div[@class="user-profile-statistics-num"]
以上就是一種簡(jiǎn)單的調(diào)試xpath方法,難的我就不介紹了,沒(méi)必要吧,如果大家覺(jué)得有必要,評(píng)論區(qū)留言,人多我就重新編輯補(bǔ)充。
三、檢查節(jié)點(diǎn)是否存在
我們使用布爾來(lái)檢查我們寫的xpath是否存在,布爾真是一個(gè)很不錯(cuò)的東西。
3.1 案例一
這里我就構(gòu)造一個(gè)xml如下:
<House> <LivingRoom> <plant name="rose"/> </LivingRoom> <TerraceGarden> <plant name="passion fruit"/> <plant name="lily"/> <plant name="golden duranta"/> </TerraceGarden></House>
使用布爾來(lái)判斷:
boolean(/House//plant)
輸出:
true
說(shuō)明該路徑正確。
3.2 案例二
假設(shè)有這樣一個(gè)xml:
<Animal> <legs>4</legs> <eyes>2</eyes> <horns>2</horns> <tail>1</tail></Animal>
使用布爾判斷:
boolean(/Animal/tusks)
輸出:
false
說(shuō)明這個(gè)路徑是錯(cuò)的。
四、檢查節(jié)點(diǎn)的文本是否為空
語(yǔ)法:
- 布爾(路徑到節(jié)點(diǎn)/文本())
- 字符串(路徑節(jié)點(diǎn))!= ‘’ ”
其他用途:
- 檢查節(jié)點(diǎn)是否存在
- 檢查參數(shù)是否不是數(shù)字 (NaN) 或 0
4.1 案例一
假設(shè)我構(gòu)造這樣一個(gè)xml:
<Deborah> <address>Dark world</address> <master>Babadi</master> <ID>#0</ID> <colour>red</colour> <side>evil</side></Deborah>
用布爾判斷:
boolean(/Deborah/master/text())
或者用string判斷:
string(/Deborah/master) != ""
輸出都為:
true
說(shuō)明文本不為空。
4.2 案例二
假設(shè)我構(gòu)造這樣一個(gè)xml:
<Dobby> <address>Hogwartz</address> <master></master> <colour>wheatish</colour> <side>all good</side></Dobby>
用布爾判斷:
boolean(/Dobby/master/text())
或者用string判斷:
string(/Dobby/master) != ""
輸出:
false
說(shuō)明文本為空。
五、通過(guò)屬性查詢
說(shuō)一些比較常見的語(yǔ)法:
- /從當(dāng)前節(jié)點(diǎn)選取直接子節(jié)點(diǎn)
- //從當(dāng)前節(jié)點(diǎn)選取子孫節(jié)點(diǎn)
- .選取當(dāng)前節(jié)點(diǎn)
- …選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)
- @選取屬性
- *代表所有
例如:
//title[@lang=’chuan’]
這就是一個(gè) XPath 規(guī)則,它就代表選擇所有名稱為 title,同時(shí)屬性 lang 的值為 chuan的節(jié)點(diǎn)。
5.1 查找具有特定屬性的節(jié)點(diǎn)
假設(shè)有這樣一個(gè)xml:
<Galaxy> <name>Milky Way</name> <CelestialObject name="Earth" type="planet"/> <CelestialObject name="Sun" type="star"/></Galaxy>
路徑匹配如下:
/Galaxy/*[@name]
或者:
//*[@name]
輸出:
<CelestialObject name="Earth" type="planet" /><CelestialObject name="Sun" type="star" />
5.2 通過(guò)屬性值的子串匹配來(lái)查找節(jié)點(diǎn)
假設(shè)有如下例子:
<Galaxy> <name>Milky Way</name> <CelestialObject name="Earth" type="planet"/> <CelestialObject name="Sun" type="star"/></Galaxy>
路徑:
/Galaxy/*[contains(@name,"Ear")]
值得補(bǔ)充的是,這里的contains函數(shù)就是代表包含的意思,這里就是查找Galaxy路徑下,所有name屬性中含有Ear的節(jié)點(diǎn)。
如上,我們也可以如下方式匹配:
//*[contains(@name,"Ear")]
雙引號(hào)也可以用來(lái)代替單引號(hào):
/Galaxy/*[contains(@name, "Ear")]
輸出:
<CelestialObject name="Earth" type="planet" />
5.3 通過(guò)屬性值的子字符串匹配查找節(jié)點(diǎn)(不區(qū)分大小寫)
假設(shè)有xml如下:
<Galaxy> <name>Milky Way</name> <CelestialObject name="Earth" type="planet"/> <CelestialObject name="Sun" type="star"/></Galaxy>
路徑
/Galaxy/*[contains(lower-case(@name),"ear")]
這里又出現(xiàn)了新的東西,加入 lower-case() 函數(shù)就是來(lái)保證我們可以包括所有的大小寫情況。
路徑
/Galaxy/*[contains(lower-case(@name),"ear")]
或者
//*[contains(lower-case(@name),"ear")]
或者,使用雙引號(hào)中的字符串:
//*[contains(lower-case(@name), "ear")]
輸出
<CelestialObject name="Earth" type="planet" />
5.4 通過(guò)匹配屬性值末尾的子字符串查找節(jié)點(diǎn)
假設(shè)有xml如下:
<Galaxy> <name>Milky Way</name> <CelestialObject name="Earth" type="planet"/> <CelestialObject name="Sun" type="star"/></Galaxy>
路徑
/Galaxy/*[ends-with(lower-case(@type),"tar")]
補(bǔ)充:這里又出現(xiàn)了新的函數(shù),ends-with就是匹配以xx結(jié)尾。
或者
//*[ends-with(lower-case(@type),"tar")]
輸出
<CelestialObject name="Sun" type="star" />
5.5 通過(guò)匹配屬性值開頭的子字符串查找節(jié)點(diǎn)
假設(shè)有這個(gè)xml:
<Galaxy> <name>Milky Way</name> <CelestialObject name="Earth" type="planet"/> <CelestialObject name="Sun" type="star"/></Galaxy>
路徑
/Galaxy/*[starts-with(lower-case(@name),"ear")]
補(bǔ)充:這里又出現(xiàn)了新的函數(shù),starts-with就是匹配以什么開頭。
或者
//*[starts-with(lower-case(@name),"ear")]
輸出
<CelestialObject name="Earth" type="planet" />
5.6 查找具有特定屬性值的節(jié)點(diǎn)
假設(shè)有這個(gè)xml:
<Galaxy> <name>Milky Way</name> <CelestialObject name="Earth" type="planet"/> <CelestialObject name="Sun" type="star"/></Galaxy>
路徑
/Galaxy/*[@name="Sun"]
補(bǔ)充:這里就是我開頭說(shuō)到的,星號(hào)代表所有,@用來(lái)選取屬性
或者
//*[@name="Sun"]
輸出
<CelestialObject name="Sun" type="star" />
六、查找包含特定屬性的元素
6.1 查找具有特定屬性的所有元素(1)
假設(shè)有xml如下:
<root> <element foobar="hello_world" /> <element example="this is one!" /></root>
xpath匹配:
/root/element[@foobar]
返回:
<element foobar="hello_world" />
6.2 查找具有特定屬性值的所有元素(2)
假設(shè)有xml如下:
<root> <element foobar="hello_world" /> <element example="this is one!" /></root>
以下 XPath 表達(dá)式:
/root/element[@foobar = "hello_world"]
將返回
也可以使用雙引號(hào):
/root/element[@foobar="hello_world"]
粉絲群:970353786
七、查找包含特定文本的元素
假設(shè)有xml如下:
<root> <element>hello</element> <another> hello </another> <example>Hello, <nested> I am an example </nested>.</example></root>
以下 XPath 表達(dá)式:
//*[text() = "hello"]
將返回hello
元素,但不返回元素。這是因?yàn)樵?code>元素包含hello文本周圍的空格。
要同時(shí)檢索and
,可以使用:
//*[normalize-space(text()) = "hello"]
補(bǔ)充:這里又多了新的函數(shù),normalize-space作用就是去除空白的意思。
要查找包含特定文本的元素,您可以使用該contains函數(shù)。以下表達(dá)式將返回
元素:
//example[contains(text(), "Hello")]
如果要查找跨越多個(gè)子/文本節(jié)點(diǎn)的文本,則可以使用.代替text()。.指元素及其子元素的整個(gè)文本內(nèi)容。
例如:
//example[. = "Hello, I am an example ."]
要查看多個(gè)文本節(jié)點(diǎn),您可以使用:
//example//text()
這將返回:
- “hello, ”
- “I am an example”
- “.”
為了更清楚地看到一個(gè)元素的整個(gè)文本內(nèi)容,可以使用該string函數(shù):
string(//example[1])
要不就
string(//example)
依然返回:
Hello, I am an example .
八、多次強(qiáng)調(diào)的語(yǔ)法
8.1 XPath 軸的語(yǔ)法
現(xiàn)在我們要補(bǔ)充新的東西,又要開始記住了:
ancestor 選取當(dāng)前節(jié)點(diǎn)的所有先輩(父、祖父等)。ancestor-or-self 選取當(dāng)前節(jié)點(diǎn)的所有先輩(父、祖父等)以及當(dāng)前節(jié)點(diǎn)本身。attribute 選取當(dāng)前節(jié)點(diǎn)的所有屬性。child 選取當(dāng)前節(jié)點(diǎn)的所有子元素。descendant 選取當(dāng)前節(jié)點(diǎn)的所有后代元素(子、孫等)。descendant-or-self 選取當(dāng)前節(jié)點(diǎn)的所有后代元素(子、孫等)以及當(dāng)前節(jié)點(diǎn)本身。following 選取文檔中當(dāng)前節(jié)點(diǎn)的結(jié)束標(biāo)簽之后的所有節(jié)點(diǎn)。namespace 選取當(dāng)前節(jié)點(diǎn)的所有命名空間節(jié)點(diǎn)。parent 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。preceding 選取文檔中當(dāng)前節(jié)點(diǎn)的開始標(biāo)簽之前的所有節(jié)點(diǎn)。preceding-sibling 選取當(dāng)前節(jié)點(diǎn)之前的所有同級(jí)節(jié)點(diǎn)。self 選取當(dāng)前節(jié)點(diǎn)。
8.2 XPath選取節(jié)點(diǎn)語(yǔ)法
為什么我在這里又來(lái)強(qiáng)調(diào)一下?因?yàn)楹苤匾?/p>
nodename 選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)。/ 從根節(jié)點(diǎn)選取。// 從匹配選擇的當(dāng)前節(jié)點(diǎn)選擇文檔中的節(jié)點(diǎn),而不考慮它們的位置。. 選取當(dāng)前節(jié)點(diǎn)。.. 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。@ 選取屬性。
在下面的表格中,列出了一些路徑表達(dá)式以及表達(dá)式的結(jié)果:
bookstore 選取 bookstore 元素的所有子節(jié)點(diǎn)。/bookstore 選取根元素 bookstore。 注釋:假如路徑起始于正斜杠( / ),則此路徑始終代表到某元素的絕對(duì)路徑!bookstore/book 選取屬于 bookstore 的子元素的所有 book 元素。//book 選取所有 book 子元素,而不管它們?cè)谖臋n中的位置。bookstore//book 選擇屬于 bookstore 元素的后代的所有 book 元素,而不管它們位于 bookstore 之下的什么位置。//@lang 選取名為 lang 的所有屬性。
8.3 Xpath謂語(yǔ)
謂語(yǔ)用來(lái)查找某個(gè)特定的節(jié)點(diǎn)或者包含某個(gè)指定的值的節(jié)點(diǎn)。謂語(yǔ)被嵌在方括號(hào)中。
看一些例子就知道了:
路徑表達(dá)式 結(jié)果/bookstore/book[1] 選取屬于 bookstore 子元素的第一個(gè) book 元素。/bookstore/book[last()] 選取屬于 bookstore 子元素的最后一個(gè) book 元素。/bookstore/book[last()-1] 選取屬于 bookstore 子元素的倒數(shù)第二個(gè) book 元素。/bookstore/book[position()<3] 選取最前面的兩個(gè)屬于 bookstore 元素的子元素的 book 元素。//title[@lang] 選取所有擁有名為 lang 的屬性的 title 元素。//title[@lang="eng"] 選取所有 title 元素,且這些元素?fù)碛兄禐?eng 的 lang 屬性。/bookstore/book[price>35.00] 選取 bookstore 元素的所有 book 元素,且其中的 price 元素的值須大于 35.00。/bookstore/book[price>35.00]/title 選取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值須大于 35.00。
8.4 Xpath選取未知節(jié)點(diǎn)
XPath 通配符可用來(lái)選取未知的 XML 元素。
通配符 描述* 匹配任何元素節(jié)點(diǎn)。@* 匹配任何屬性節(jié)點(diǎn)。node() 匹配任何類型的節(jié)點(diǎn)。
在下面的表格中,我們列出了一些路徑表達(dá)式,以及這些表達(dá)式的結(jié)果:
路徑表達(dá)式 結(jié)果/bookstore/* 選取 bookstore 元素的所有子元素。//* 選取文檔中的所有元素。//title[@*] 選取所有帶有屬性的 title 元素。
8.5 Xpath選取若干路徑
通過(guò)在路徑表達(dá)式中使用“|”運(yùn)算符,您可以選取若干個(gè)路徑。
在下面的表格中,列出了一些路徑表達(dá)式,以及這些表達(dá)式的結(jié)果:
路徑表達(dá)式 結(jié)果//book/title | //book/price 選取 book 元素的所有 title 和 price 元素。//title | //price 選取文檔中的所有 title 和 price 元素。/bookstore/book/title | //price 選取屬于 bookstore 元素的 book 元素的所有 title 元素,以及文檔中所有的 price 元素。
九、獲取相對(duì)于當(dāng)前節(jié)點(diǎn)的節(jié)點(diǎn)
假設(shè)我們有xml如下:
<?xml version="1.0" encoding="ISO-8859-1"?><bookstore><book> <title lang="eng">Harry Potter</title> <price>29.99</price></book><book> <title lang="eng">Learning XML</title> <price>39.95</price></book></bookstore>
9.1 基本語(yǔ)法
其實(shí)這些內(nèi)容,大可不必都掌握,但是你一定要知道,你想用的時(shí)候,再來(lái)本文查一下會(huì)用就行。
這是相關(guān)實(shí)例:
問(wèn)題是:這里提到的祖先,孩子,兄弟,父母節(jié)點(diǎn),大家知道嗎?如果你會(huì)html的話,你應(yīng)該知道。超過(guò)2000贊我可以出一篇html的教程,本篇我就暫時(shí)默認(rèn)大家知道了。
9.2 尋找祖先節(jié)點(diǎn)
假設(shè)有xml如下:(這里已經(jīng)很形象說(shuō)明了祖先,孩子,兄弟,父母節(jié)點(diǎn)的關(guān)系了,仔細(xì)看看)
<GrandFather name="Bardock" gender="male" spouse="Gine"> <Dad name="Goku" gender="male" spouse="Chi Chi"> <Me name="Gohan" gender="male"/> <brother name="Goten" gender="male"/> </Dad></GrandFather>
路徑
//Me/ancestor::node()
輸出:
<GrandFather name="Bardock" gender="male" spouse="Gine"> <Dad name="Goku" gender="male" spouse="Chi Chi"> <Me name="Gohan" gender="male" /> <brother name="Goten" gender="male" /> </Dad></GrandFather><Dad name="Goku" gender="male" spouse="Chi Chi"> <Me name="Gohan" gender="male" /> <brother name="Goten" gender="male" /></Dad>
9.4 尋找兄弟節(jié)點(diǎn)
假設(shè)有xml如下:
<GrandFather name="Bardock" gender="male" spouse="Gine"> <Dad name="Goku" gender="male" spouse="Chi Chi"> <brother name="Goten" gender="male" /> <Me name="Gohan" gender="male" /> <brother name="Goten" gender="male" /> </Dad></GrandFather>
路徑:
//Me/following-sibling::brother
輸出:
<brother name="Goten" gender="male" />
9.5 尋找祖父節(jié)點(diǎn)(2)
假設(shè)有xml如下:
<GrandFather name="Bardock" gender="male" spouse="Gine"> <Dad name="Goku" gender="male" spouse="Chi Chi"> <Me name="Gohan" gender=
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/122211.html
摘要:標(biāo)簽不區(qū)分大小寫,但推薦小寫。標(biāo)簽可以嵌套,但不能交叉嵌套。標(biāo)簽也稱為元素。比如行內(nèi)標(biāo)簽亦可成行內(nèi)元素。 ??HTML必備知識(shí)詳解?? 第一部分:HTML框架簡(jiǎn)介...
摘要:今天,一條就帶大家徹底跨過(guò)排序算法這道坎,保姆級(jí)教程建議收藏。利用遞歸算法,對(duì)分治后的子數(shù)組進(jìn)行排序。基本思想堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)而設(shè)計(jì)的一種排序算法,堆排序是一種選擇排序,它的最壞,最好,平均時(shí)間復(fù)雜度均為,它也是不穩(wěn)定排序。 ...
文章目錄 強(qiáng)烈推薦系列教程,建議學(xué)起來(lái)!! 一.pycharm下載安裝二.python下載安裝三.pycharm上配置python四.配置鏡像源讓你下載嗖嗖的快4.1pycharm內(nèi)部配置 4.2手動(dòng)添加鏡像源4.3永久配置鏡像源 五.插件安裝(比如漢化?)5.1自動(dòng)補(bǔ)碼神器第一款5.2漢化pycharm5.3其它插件 六.美女背景七.自定義腳本開頭八、這個(gè)前言一定要看九、pyt...
閱讀 3249·2023-04-25 22:47
閱讀 3765·2021-10-11 10:59
閱讀 2299·2021-09-07 10:12
閱讀 4242·2021-08-11 11:15
閱讀 3432·2019-08-30 13:15
閱讀 1749·2019-08-30 13:00
閱讀 968·2019-08-29 14:02
閱讀 1679·2019-08-26 13:57