1. 程式人生 > >python3 xpath獲取同級元素的各種方法

python3 xpath獲取同級元素的各種方法

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-childnth-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節點。

 轉原貼地址:https://www.cnblogs.com/VseYoung/p/8686383.html