Python selenium —— 父子、兄弟、相鄰節(jié)點(diǎn)定位方式詳解

今天跟大家分享下selenium中根據(jù)父子、兄弟、相鄰節(jié)點(diǎn)定位的方法,很多人在實(shí)際應(yīng)用中會(huì)遇到想定位的節(jié)點(diǎn)無法直接定位,需要通過附近節(jié)點(diǎn)來相對(duì)定位的問題,但從父節(jié)點(diǎn)定位子節(jié)點(diǎn)容易,從子節(jié)點(diǎn)定位父節(jié)點(diǎn)、定位一個(gè)節(jié)點(diǎn)的哥哥節(jié)點(diǎn)就一籌莫展了,別急,且看博主一步步講解。

1. 由父節(jié)點(diǎn)定位子節(jié)點(diǎn)

最簡(jiǎn)單的肯定就是由父節(jié)點(diǎn)定位子節(jié)點(diǎn)了,我們有很多方法可以定位,下面上個(gè)例子:

對(duì)以下代碼:

<html>
<body>
<div id="A">
    <!--父節(jié)點(diǎn)定位子節(jié)點(diǎn)-->
    <div id="B">
        <div>parent to child</div>
    </div>
</div>
</body>
</html>

想要根據(jù) B節(jié)點(diǎn) 定位無id的子節(jié)點(diǎn),代碼示例如下:

# -*- coding: utf-8 -*-
from selenium import webdriver

driver = webdriver.Firefox()
driver.get('D:\\py\\AutoTestFramework\\src\\others\\test.html')

# 1.串聯(lián)尋找
print driver.find_element_by_id('B').find_element_by_tag_name('div').text

# 2.xpath父子關(guān)系尋找
print driver.find_element_by_xpath("http://div[@id='B']/div").text

# 3.css selector父子關(guān)系尋找
print driver.find_element_by_css_selector('div#B>div').text

# 4.css selector nth-child
print driver.find_element_by_css_selector('div#B div:nth-child(1)').text

# 5.css selector nth-of-type
print driver.find_element_by_css_selector('div#B div:nth-of-type(1)').text

# 6.xpath軸 child
print driver.find_element_by_xpath("http://div[@id='B']/child::div").text

driver.quit()

結(jié)果:

parent to child
parent to child
parent to child
parent to child
parent to child
parent to child

第1到第3都是我們熟悉的方法,便不再多言。第4種方法用到了css選擇器:nth-child(n),該選擇器返回第n個(gè)節(jié)點(diǎn),該節(jié)點(diǎn)為div標(biāo)簽;第5種方法用到了另一個(gè)css選擇器: nth-of-type(n),該選擇器返回第n個(gè)div標(biāo)簽,注意與上一個(gè)選擇器的區(qū)別;第6種方法用到了xpath軸 child,這個(gè)是xpath默認(rèn)的軸,可以忽略不寫,其實(shí)質(zhì)是跟方法2一樣的。

當(dāng)然,css中還有一些選擇器是可以選擇父子關(guān)系的如last-child、nth-last-child等,感興趣可以自行百度,有機(jī)會(huì)博主會(huì)講講css selector。

2. 由子節(jié)點(diǎn)定位父節(jié)點(diǎn)

由子節(jié)點(diǎn)想要定位到父節(jié)點(diǎn)就有點(diǎn)難度了,對(duì)以下代碼:

<html>
<body>
<div id="A">
    <!--子節(jié)點(diǎn)定位父節(jié)點(diǎn)-->
    <div>
        <div>child to parent
            <div>
                <div id="C"></div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

我們想要由 C節(jié)點(diǎn) 定位其兩層父節(jié)點(diǎn)的div,示例代碼如下:

# -*- coding: utf-8 -*-
from selenium import webdriver

driver = webdriver.Firefox()
driver.get('D:\\py\\AutoTestFramework\\src\\others\\test.html')

# 1.xpath: `.`代表當(dāng)前節(jié)點(diǎn); '..'代表父節(jié)點(diǎn)
print driver.find_element_by_xpath("http://div[@id='C']/../..").text

# 2.xpath軸 parent
print driver.find_element_by_xpath("http://div[@id='C']/parent::*/parent::div").text

driver.quit()

結(jié)果:

child to parent
child to parent

這里我們有兩種辦法,第1種是 .. 的形式,就像我們知道的,. 表示當(dāng)前節(jié)點(diǎn),.. 表示父節(jié)點(diǎn);第2種辦法跟上面一樣,是xpath軸中的一個(gè):parent,取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。這里也是css selector的一個(gè)痛點(diǎn),因?yàn)閏ss的設(shè)計(jì)不允許有能夠獲取父節(jié)點(diǎn)的辦法(至少目前沒有)

3. 由弟弟節(jié)點(diǎn)定位哥哥節(jié)點(diǎn)

這是第3、第4種情況,我們這里要定位的是兄弟節(jié)點(diǎn)了。如以下源碼:

<html>
<body>
<div id="A">
    <!--下面兩個(gè)節(jié)點(diǎn)用于兄弟節(jié)點(diǎn)定位-->
    <div>brother 1</div>
    <div id="D"></div>
    <div>brother 2</div>
</div>
</body>
</html>

怎么通過 D節(jié)點(diǎn) 定位其哥哥節(jié)點(diǎn)呢?看代碼示例:

# -*- coding: utf-8 -*-
from selenium import webdriver

driver = webdriver.Firefox()
driver.get('D:\\Code\\py\\AutoTestFramework\\src\\others\\test.html')

# 1.xpath,通過父節(jié)點(diǎn)獲取其哥哥節(jié)點(diǎn)
print driver.find_element_by_xpath("http://div[@id='D']/../div[1]").text

# 2.xpath軸 preceding-sibling
print driver.find_element_by_xpath("http://div[@id='D']/preceding-sibling::div[1]").text

driver.quit()

結(jié)果

brother 1
brother 1

這里博主也列舉了兩種方法,一種是通過該節(jié)點(diǎn)的父節(jié)點(diǎn)來獲得哥哥節(jié)點(diǎn),另外一種比較優(yōu)雅,是通過 xpath軸:preceding-sibling,其能夠獲取當(dāng)前節(jié)點(diǎn)的所有同級(jí)哥哥節(jié)點(diǎn),注意括號(hào)里的標(biāo)號(hào),1 代表著離當(dāng)前節(jié)點(diǎn)最近的一個(gè)哥哥節(jié)點(diǎn),數(shù)字越大表示離當(dāng)前節(jié)點(diǎn)越遠(yuǎn),當(dāng)然,xpath軸:preceding也可以,但是使用起來比較復(fù)雜,它獲取到的是該節(jié)點(diǎn)之前的所有非祖先節(jié)點(diǎn)(這里不太好解釋,改天專門寫篇博文講解下所有的軸)

4. 由哥哥節(jié)點(diǎn)定位弟弟節(jié)點(diǎn)

源碼與 3 一致,要想通過 D節(jié)點(diǎn) 定位其弟弟節(jié)點(diǎn),看代碼示例:

# -*- coding: utf-8 -*-
from selenium import webdriver

driver = webdriver.Firefox()
driver.get('D:\\Code\\py\\AutoTestFramework\\src\\others\\test.html')

# 1.xpath,通過父節(jié)點(diǎn)獲取其弟弟節(jié)點(diǎn)
print driver.find_element_by_xpath("http://div[@id='D']/../div[3]").text

# 2.xpath軸 following-sibling
print driver.find_element_by_xpath("http://div[@id='D']/following-sibling::div[1]").text

# 3.xpath軸 following
print driver.find_element_by_xpath("http://div[@id='D']/following::*").text

# 4.css selector +
print driver.find_element_by_css_selector('div#D + div').text

# 5.css selector ~
print driver.find_element_by_css_selector('div#D ~ div').text

driver.quit()

結(jié)果:

brother 2
brother 2
brother 2
brother 2
brother 2

博主分享了五種方法定位其弟弟節(jié)點(diǎn),上面三種是用xpath,第一種很好理解,第二種用到了xpath軸:following-sibling,跟preceding-sibling類似,它的作用是獲取當(dāng)前節(jié)點(diǎn)的所有同級(jí)弟弟節(jié)點(diǎn),同樣,1 代表離當(dāng)前節(jié)點(diǎn)最近的一個(gè)弟弟節(jié)點(diǎn),數(shù)字越大表示離當(dāng)前節(jié)點(diǎn)越遠(yuǎn);第三種用到了xpath軸:following,獲取到該節(jié)點(diǎn)之后所有節(jié)點(diǎn),除了祖先節(jié)點(diǎn)(跟preceding方向相反,但因?yàn)橥马樞蛉菀鬃x,不容易出錯(cuò),所以也是可以用來獲取弟弟節(jié)點(diǎn)的,但也不建議這么使用);第四、第五種,我們用到了css selector,+~ 的區(qū)別是: + 表示緊跟在當(dāng)前節(jié)點(diǎn)之后的div節(jié)點(diǎn),~ 表示當(dāng)前節(jié)點(diǎn)之后的div節(jié)點(diǎn),如果用find_elements,則可獲取到一組div節(jié)點(diǎn)。

以上就是博主今天分享的內(nèi)容,通過這些方法,你可以隨意根據(jù)一個(gè)元素定位到其他任何一個(gè)位置的元素,這樣,相對(duì)元素定位再不是難事了吧。有什么問題給我留言吧。


附上一份博主總結(jié)的XPath、CSS定位速查表,在寫自動(dòng)化定位過程中遇到不確定的定位方法可以通過此表速查

XPath、CSS定位速查表

xpath css cheat sheet

HTML版如下:

描述 Xpath CSS Path
直接子元素 //div/a div > a
子元素或后代元素 //div//a div a
以id定位 //div[@id=’idValue’]//a div#idValue a
以class定位 //div[@class=’classValue’]//a div.classValue a
同級(jí)弟弟元素 //ul/li[@class=’first’]/following-sibling::li ul>li.first + li
屬性 //form/input[@name=’username’] form input[name=’username’]
多個(gè)屬性 //input[@name=’continue’ and @type=‘button’] input[name=’continue’][type=’button’]
第4個(gè)子元素 //ul[@id=’list’]/li[4] ul#list li:nth-child(4)
第1個(gè)子元素 //ul[@id=’list’]/li[1] ul#list li:first-child
最后1個(gè)子元素 //ul[@id=’list’]/li[last()] ul#list li:last-child
屬性包含某字段 //div[contains(@title,’Title’)] div[title*=”Title”]
屬性以某字段開頭 //input[starts-with(@name,’user’)] input[name^=”user”]
屬性以某字段結(jié)尾 //input[ends-with(@name,’name’)] input[name$=”name”]
text中包含某字段 //div[contains(text(), 'text')] 無法定位
元素有某屬性 //div[@title] div[title]
父節(jié)點(diǎn) //div/.. 無法定位
同級(jí)哥哥節(jié)點(diǎn) //li/preceding-sibling::div[1] 無法定位

如果它對(duì)你有幫助,或者你有什么好的建議,請(qǐng)告訴我。

pdf版本可在此下載 xpath css cheat sheet by 灰藍(lán)


更多關(guān)于python selenium的文章,請(qǐng)關(guān)注我的CSDN專欄:Python Selenium自動(dòng)化測(cè)試詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容