XPath軸(XPath Axes)可定義某個相對於當前節點的節點集:
1、child 選取當前節點的所有子元素
2、parent 選取當前節點的父節點
3、descendant 選取當前節點的所有后代元素(子、孫等)
4、ancestor 選取當前節點的所有先輩(父、祖父等)
5、descendant-or-self 選取當前節點的所有后代元素(子、孫等)以及當前節點本身
6、ancestor-or-self 選取當前節點的所有先輩(父、祖父等)以及當前節點本身
7、preceding-sibling 選取當前節點之前的所有同級節點
8、following-sibling 選取當前節點之后的所有同級節點
9、preceding 選取文檔中當前節點的開始標簽之前的所有節點
10、following 選取文檔中當前節點的結束標簽之后的所有節點
11、self 選取當前節點
12、attribute 選取當前節點的所有屬性
13、namespace 選取當前節點的所有命名空間節點
如:要定位當前td同級后的一個td
//td[.='text']/following-sibling::td
following-sibling 選取當前節點之后的所有同級節點,跟preceding-sibling一樣都是選取同級同父的節點,只不過following是取對應節點之后的節點,preceding-sibling取的是該節點之前的節點。
/AAA/BBB/following-sibling::* 取/AAA/BBB節點的之后的所有同級節點
<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//CCC/following-sibling::* 選取所有CCC元素的之后所有同級節點
<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
今天跟大家分享下selenium中根據父子、兄弟、相鄰節點定位的方法,很多人在實際應用中會遇到想定位的節點無法直接定位,需要通過附近節點來相對定位的問題,但從父節點定位子節點容易,從子節點定位父節點、定位一個節點的哥哥節點就一籌莫展了,別急,且看博主一步步講解。
1. 由父節點定位子節點
最簡單的肯定就是由父節點定位子節點了,我們有很多方法可以定位,下面上個例子:
對以下代碼:
<html> <body> <div id="A"> <!--父節點定位子節點--> <div id="B"> <div>parent to child</div> </div> </div> </body> </html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
想要根據 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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
結果:
parent to child parent to child parent to child parent to child parent to child parent to child
- 1
- 2
- 3
- 4
- 5
- 6
第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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
我們想要由 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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
結果:
child to parent child to parent
- 1
- 2
這里我們有兩種辦法,第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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
怎么通過 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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
結果
brother 1
brother 1
- 1
- 2
這里博主也列舉了兩種方法,一種是通過該節點的父節點來獲得哥哥節點,另外一種比較優雅,是通過 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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
結果:
brother 2
brother 2
brother 2
brother 2
brother 2
- 1
- 2
- 3
- 4
- 5
博主分享了五種方法定位其弟弟節點,上面三種是用xpath,第一種很好理解,第二種用到了xpath軸:following-sibling
,跟preceding-sibling
類似,它的作用是獲取當前節點的所有同級弟弟節點,同樣,1
代表離當前節點最近的一個弟弟節點,數字越大表示離當前節點越遠;第三種用到了xpath軸:following
,獲取到該節點之后所有節點,除了祖先節點(跟preceding
方向相反,但因為往下順序容易讀,不容易出錯,所以也是可以用來獲取弟弟節點的,但也不建議這么使用);第四、第五種,我們用到了css selector,+
和 ~
的區別是: +
表示緊跟在當前節點之后的div節點,~
表示當前節點之后的div節點,如果用find_elements,則可獲取到一組div節點。