使用selenium進行自動化時少不了對元素進行定位,但目前前端大多使用框架vue,angular等,很多元素并沒有id,name等這些讓我們很容易定位的元素屬性,這時候就要用到xpath進行定位了,而利用xpath中的軸可以很輕松的精確定位到你要的元素
一、xpath軸
xpath的基礎(chǔ)語法和謂語可看網(wǎng)上的一些文檔(http://www.runoob.com/xpath/xpath-syntax.html)

Axes
二、實例
具體使用方法示例為:parent::div,即軸名稱::標(biāo)簽名,挑上圖一些用實例進行分析
- parent 選取當(dāng)前節(jié)點的父節(jié)點,也就是當(dāng)前節(jié)點上一級節(jié)點
示例://div[contains(text(),'產(chǎn)證地址')]/parent::td
前半段//div[contains(text(),'產(chǎn)證地址')]為找到內(nèi)容包含產(chǎn)證地址的div節(jié)點(圈出來的節(jié)點)然后它的上一級節(jié)點 parent::td,即黃色部分

image.png
- child 選取當(dāng)前節(jié)點的子節(jié)點,也就是當(dāng)前節(jié)點的下一級節(jié)點
示例://td[@width='50%']//child::div
前半段//td[@width='50%'] 為找到屬性width為50%的td節(jié)點(紅框圈出來的地方),然后它的下一級節(jié)點child::div,即黃色部分

image.png
- ancestor 選取當(dāng)前節(jié)點的所有上層節(jié)點
示例://div[contains(text(),'產(chǎn)證地址')]//ancestor::table
前半段//div[contains(text(),'產(chǎn)證地址')]為找到內(nèi)容包含產(chǎn)證地址的div節(jié)點,然后找到它的上層節(jié)點中的table節(jié)點
注意:ancestor只能找上層節(jié)點,如果是上層節(jié)點的兄弟節(jié)點是找不到的
//div[contains(text(),'產(chǎn)證地址')]//ancestor::p,像這樣是找不到table節(jié)點的兄弟節(jié)點p的

image.png
- descendant 選取當(dāng)前節(jié)點的所有下層節(jié)點
實例 ://td[@width='50%']/descendant::p

image.png
-
following 選取當(dāng)前節(jié)點之后顯示的所有節(jié)點
示例://td[@width='50%']/following::div[contains(text(),'行政區(qū)域')]
//td[@width='50%']為圈出來的節(jié)點,following::div[contains(text(),'行政區(qū)域')]找到它之后的所有節(jié)點中text內(nèi)容包含行政區(qū)域的節(jié)點(黃色部分)
following following-sibling 選取當(dāng)前節(jié)點之后所有的兄弟(平級)節(jié)點
示例://p[text()='物業(yè)信息']/following-sibling::p[@id='ownerPart']
//p[text()='物業(yè)信息'] 找到內(nèi)容為物業(yè)信息的節(jié)點(圈出來的部分),following-sibling::p[@id='ownerPart'] 然后找到它的兄弟節(jié)點中id為ownerPart的節(jié)點(黃色部分)

image.png
- preceding 選取當(dāng)前節(jié)點前面所有的節(jié)點
示例://p[text()='出售方信息']/preceding::div[contains(text(),'擬定網(wǎng)簽價')]
//p[text()='出售方信息'],紅色框圈出來的部分preceding::div[contains(text(),'擬定網(wǎng)簽價')]找到前面所有節(jié)點中text內(nèi)容包含擬定網(wǎng)簽價的div節(jié)點(黃色部分)

preceding
- preceding-sibling 選取當(dāng)前節(jié)點前面所有兄弟(平級)節(jié)點
示例://p[text()='出售方信息']/preceding-sibling::p[contains(text(),'物業(yè)信息')]
//p[text()='出售方信息'] 紅色框圈出來部分
preceding-sibling::p[contains(text(),'物業(yè)信息')] 找到它前面的所有兄弟節(jié)點中內(nèi)容包含物業(yè)信息的p節(jié)點(黃色部分)

image.png
三、小tips
- 謂語:
starts-with 顧名思義,匹配一個屬性開始位置的關(guān)鍵字
contains 匹配一個屬性值中包含的字符串
text() 匹配的是顯示文本信息,此處也可以用來做定位用
//input[starts-with(@name,'name1')] 查找name屬性中開始位置包含'name1'關(guān)鍵字的頁面元素
//input[contains(@name,'na')] 查找name屬性中包含na關(guān)鍵字的頁面元素
<a >百度搜索</a>
xpath寫法為 //a[text()='百度搜索']
或者 //a[contains(text(),"百度搜索")] - .// 和//的區(qū)別
//是指從全文上下文中搜索//后面的節(jié)點
.// 中.表示當(dāng)前節(jié)點,.//表示從當(dāng)前節(jié)點之后的子節(jié)點中查找(或指從前面的節(jié)點的子節(jié)點中進行查找)
例如://div[.//a[text()=’SELENIUM’]] 為從任意div中查找其子節(jié)點文本為SELENIUM的a元素 - 凡是用text()的地方均可以直接用.來進行表示,例如a[text()=’SELENIUM’]和a[.=’SELENIUM’]是等價的。
四、個人心得
- 1、定位元素先看改元素在頁面中有沒有唯一性的屬性或內(nèi)容,有就可以根據(jù)這個來定位
例如:
//a[text()='確定']
//input[@placeholder='請輸入,若無則無需填寫'] - 2、如果沒有唯一性的屬性就可該元素的上下中有沒有唯一性的屬性或內(nèi)容,這樣就可以先定位它的上下元素,然后在來找你要定位的元素
例如://span[text()='貸款']/preceding-sibling::span/span
這個是先找到內(nèi)容為貸款的span節(jié)點然后找它上面的平級節(jié)點span然后在往下找一層span - 3、總體的思路就是通過節(jié)點或它的上下節(jié)點的唯一性來入手以保證你定位元素的唯一性,以下是幾個自己定位的實例
//table[.//p[text()='擁有房屋產(chǎn)權(quán)家庭一:']]//td[./p[text()='產(chǎn)權(quán)人二:']]//form//form//input[@placeholder]
.代表當(dāng)前節(jié)點
//table[.//p[text()='擁有房屋產(chǎn)權(quán)家庭一:']]//td[./p[text()='產(chǎn)權(quán)人三:']]//form//form//li[./label[contains(text(),'購入份額契稅')]]//input
//body/div[last()]//span[text()='買賣'] - 4、descendant表示選取當(dāng)前節(jié)點的所有后代元素
凡是使用descendant的地方都可以用//替換,效果一樣,都是查找后臺元素
