selenium+xpath 文本信息定位
阿新 • • 發佈:2018-07-14
索引 lis 多個 table elements -- rst 建議 src
selenium中根據父子、兄弟、相鄰節點定位的方法,很多人在實際應用中會遇到想定位的節點無法直接定位,需要通過附近節點來相對定位的問題,但從父節點定位子節點容易,從子節點定位父節點、定位一個節點的哥哥節點。
第一種方法:通過絕對路徑做定位(相信大家不會使用這種方式)
By.xpath("html/body/div/form/input")
By.xpath("//input")
第三種方法:通過元素索引定位
By.xpath("//input[4]")
第四種方法:使用xpath屬性定位(結合第2、第3中方法可以使用)
By.xpath("//input[@id=‘kw1‘]")
By.xpath("//input[@type=‘name‘ and @name=‘kw1‘]")
第五種方法:使用部分屬性值匹配(最強大的方法)
By.xpath("//input[start-with(@id,‘nice‘)
By.xpath("//input[ends-with(@id,‘很漂亮‘)
By.xpath("//input[contains(@id,‘那麽美‘)]")
1. 由父節點定位子節點
最簡單的肯定就是由父節點定位子節點了,我們有很多方法可以定位,下面上個例子:
對以下代碼:
<html>
<body>
<div id="A">
<!--父節點定位子節點-->
<div id="B">
<div>parent to child</div>
</div>
</div>
</body>
</html>
- 想要根據 B節點 定位無id的子節點,代碼示例如下:
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.get(‘D:\\py\\AutoTestFramework\\src\\others\\test.html‘)
# 1.串聯尋找
print driver.find_element_by_id(‘B‘).find_element_by_tag_name(‘div‘).text
# 2.xpath父子關系尋找
print driver.find_element_by_xpath("//div[@id=‘B‘]/div").text
# 3.css selector父子關系尋找
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("//div[@id=‘B‘]/child::div").text
driver.quit()
- 結果:
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個節點,該節點為div標簽;第5種方法用到了另一個css選擇器:nth-of-type(n)
,該選擇器返回第n個div標簽,註意與上一個選擇器的區別;第6種方法用到了xpath軸 child
,這個是xpath默認的軸,可以忽略不寫,其實質是跟方法2一樣的。
當然,css中還有一些選擇器是可以選擇父子關系的如last-child
、nth-last-child
等,感興趣可以自行百度,有機會博主會講講css selector。
2. 由子節點定位父節點
由子節點想要定位到父節點就有點難度了,對以下代碼:
<html>
<body>
<div id="A">
<!--子節點定位父節點-->
<div>
<div>child to parent
<div>
<div id="C"></div>
</div>
</div>
</div>
</div>
</body>
</html>
- 我們想要由 C節點 定位其兩層父節點的div,示例代碼如下:
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.get(‘D:\\py\\AutoTestFramework\\src\\others\\test.html‘)
# 1.xpath: `.`代表當前節點; ‘..‘代表父節點
print driver.find_element_by_xpath("//div[@id=‘C‘]/../..").text
# 2.xpath軸 parent
print driver.find_element_by_xpath("//div[@id=‘C‘]/parent::*/parent::div").text
driver.quit()
- 結果:
child to parent
child to parent
- 這裏我們有兩種辦法,第1種是
..
的形式,就像我們知道的,.
表示當前節點,..
表示父節點;第2種辦法跟上面一樣,是xpath軸中的一個:parent
,取當前節點的父節點。這裏也是css selector的一個痛點,因為css的設計不允許有能夠獲取父節點的辦法(至少目前沒有)
3. 由弟弟節點定位哥哥節點
這是第3、第4種情況,我們這裏要定位的是兄弟節點了。如以下源碼:
<html>
<body>
<div>
<!--下面兩個節點用於兄弟節點定位-->
<div>brother 1</div>
<div id="D"></div>
<div>brother 2</div>
</div>
</body>
</html>
- 怎麽通過 D節點 定位其哥哥節點呢?看代碼示例:
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.get(‘D:\\Code\\py\\AutoTestFramework\\src\\others\\test.html‘)
# 1.xpath,通過父節點獲取其哥哥節點
print driver.find_element_by_xpath("//div[@id=‘D‘]/../div[1]").text
# 2.xpath軸 preceding-sibling
print driver.find_element_by_xpath("//div[@id=‘D‘]/preceding-sibling::div[1]").text
driver.quit()
- 結果
brother 1
brother 1
- 這裏博主也列舉了兩種方法,一種是通過該節點的父節點來獲得哥哥節點,另外一種比較優雅,是通過
xpath軸:preceding-sibling
,其能夠獲取當前節點的所有同級哥哥節點,註意括號裏的標號,1
代表著離當前節點最近的一個哥哥節點,數字越大表示離當前節點越遠,當然,xpath軸:preceding
也可以,但是使用起來比較復雜,它獲取到的是該節點之前的所有非祖先節點(這裏不太好解釋,改天專門寫篇博文講解下所有的軸)
4. 由哥哥節點定位弟弟節點
源碼與 3
一致,要想通過 D節點 定位其弟弟節點,看代碼示例:
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.get(‘D:\\Code\\py\\AutoTestFramework\\src\\others\\test.html‘)
# 1.xpath,通過父節點獲取其弟弟節點
print driver.find_element_by_xpath("//div[@id=‘D‘]/../div[3]").text
# 2.xpath軸 following-sibling
print driver.find_element_by_xpath("//div[@id=‘D‘]/following-sibling::div[1]").text
# 3.xpath軸 following
print driver.find_element_by_xpath("//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()
- 結果:
brother 2
brother 2
brother 2
brother 2
brother 2
- 博主分享了五種方法定位其弟弟節點,上面三種是用xpath,第一種很好理解,第二種用到了
xpath軸:following-sibling
,跟preceding-sibling
類似,它的作用是獲取當前節點的所有同級弟弟節點,同樣,1
代表離當前節點最近的一個弟弟節點,數字越大表示離當前節點越遠;第三種用到了xpath軸:following
,獲取到該節點之後所有節點,除了祖先節點(跟preceding
方向相反,但因為往下順序容易讀,不容易出錯,所以也是可以用來獲取弟弟節點的,但也不建議這麽使用);第四、第五種,我們用到了css selector,+
和~
的區別是:+
表示緊跟在當前節點之後的div節點,~
表示當前節點之後的div節點,如果用find_elements,則可獲取到一組div節點。
XPath、CSS定位速查表
xpath css cheat sheetHTML版如下:
描述 | 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 |
同級弟弟元素 | //ul/li[@class=’first’]/following-sibling::li | ul>li.first + li |
屬性 | //form/input[@name=’username’] | form input[name=’username’] |
多個屬性 | //input[@name=’continue’ and @type=‘button’] | input[name=’continue’][type=’button’] |
第4個子元素 | //ul[@id=’list’]/li[4] | ul#list li:nth-child(4) |
第1個子元素 | //ul[@id=’list’]/li[1] | ul#list li:first-child |
最後1個子元素 | //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”] |
屬性以某字段結尾 | //input[ends-with(@name,’name’)] | input[name$=”name”] |
text中包含某字段 | //div[contains(text(), ‘text‘)] | 無法定位 |
元素有某屬性 | //div[@title] | div[title] |
父節點 | //div/.. | 無法定位 |
同級哥哥節點 | //li/preceding-sibling::div[1] | 無法定位 |
selenium+xpath 文本信息定位