『心善淵』Selenium3.0基礎 — 6、Selenium中使用XPath定位元素

繁華似錦Fighting發表於2021-06-28

前情提示:在前一篇文章中,我們詳細的介紹了XPath路徑表示式的使用方式。那麼本篇文章我們就來說說在Selenium測試框架中如何使用XPath定位元素。

XPath定位和Selenium基礎元素定位方式一樣,都可以獲取單個元素或者多個元素的結果集。

如下所示:

  1. 單數定位,獲得一個指定元素物件:
    driver.find_element_by_xpath("XPath路徑表示式")
  2. 複數定位,獲得指定元素結果集列表:
    driver.find_elements_by_xpath("XPath路徑表示式")

1、Selenium中使用XPath查詢元素

(1)XPath通過idnameclass屬性定位

"""
1.學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        相對路徑:標籤名+屬性
        //標籤名[@屬性名='屬性值']
3.需求
    在百度頁面中,使用XPath定位搜尋欄
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep

# 2.開啟瀏覽器(獲得瀏覽器物件)
driver = webdriver.Chrome()

# 3.開啟頁面
url = "http://www.baidu.com"
driver.get(url)
sleep(2)

# 4.用XPath通過id屬性定位  
"""
注意:@id='kw',等號兩邊不要有空格
有時候會報錯,SyntaxError:(語法錯誤)
"""
element1 = driver.find_element_by_xpath("//input[@id='kw']")
# 列印定位元素所在行的原始碼
print(element1.get_attribute("outerHTML"))

# 5.用XPath通過name屬性定位  
element2 = driver.find_element_by_xpath("//input[@name='wd']")
print(element2.get_attribute("outerHTML"))

# 6.用XPath通過class屬性定位  
element3 = driver.find_element_by_xpath("//*[@class='s_ipt']")
print(element3.get_attribute("outerHTML"))

# 7.關閉瀏覽器
driver.quit()

"""
輸出結果:
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""

總結

  1. 如果不想制定標籤名稱,可以用*號表示任意標籤。
  2. 有時候同一個屬性,同名的比較多,這時候可以通過標籤篩選下,定位更準一點。
  3. 如果想制定具體某個標籤,就可以直接寫標籤名稱。

(2)XPath通過標籤中的其他屬性定位

如果一個元素idnameclass屬性都沒有,這時候也可以通過其它屬性定位到。

# 需求:使用XPath通過其他屬性對百度首頁搜尋框進行定位

# 1.匯入selenium
from selenium import webdriver
from time import sleep

# 2.開啟瀏覽器(獲得瀏覽器物件)
driver = webdriver.Chrome()

# 3.開啟頁面
url = "http://www.baidu.com"
driver.get(url)
sleep(2)

# 4.用XPath通過maxlength屬性定位  
"""
注意:@id='kw',等號兩邊不要有空格
有時候會報錯,SyntaxError:(語法錯誤)
"""
element1 = driver.find_element_by_xpath("//input[@maxlength='255']")
# 列印定位元素所在行的原始碼
print(element1.get_attribute("outerHTML"))

# 5.用XPath通過autocomplete屬性定位  
element2 = driver.find_element_by_xpath("//input[@autocomplete='off']")
print(element2.get_attribute("outerHTML"))

# 6.關閉瀏覽器
driver.quit()

"""
輸出結果:
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
"""

(3)XPath層級定位

  1. 如果一個元素,它的屬性不是很明顯,無法直接定位到,這時候我們可以先找它老爸(父元素)。
  2. 找到它老爸後,再找下個層級就能定位到了。
  3. 如下圖圖所示,要定位的是input這個標籤,它的老爸的class=’s_ipt_wr‘
  4. 要是它老爸的屬性也不是很明顯,就找它爺爺id=form
  5. 於是就可以通過層級關係定位到。

image

示例

需求:在頁面中,定位下面程式碼片段中的<input>標籤

<p id="p1">
    <label for="userA">賬號A</label>
    <input required="" value="">
</p>

程式碼指令碼:

"""
1.學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        層級定位 :
        //父標籤名[@父標籤屬性名='屬性值']/子標籤
        注意:最終定位的是子標籤
3.需求
    在頁面中,使用XPath定位上面程式碼片段的<input>標籤
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟註冊A頁面
url = "file:///" + os.path.abspath("./練習頁面/註冊A.html")
driver.get(url)
sleep(2)

# 4.XPath層級定位,通過p標籤定位字標籤input標籤
textA = driver.find_element_by_xpath("//p[@id='p1']/input")
print(textA.get_attribute("outerHTML"))

# 6.關閉瀏覽器
driver.quit()

"""
輸出結果:
<input required="" value="">
"""

(4)XPath索引定位

  1. 如果一個元素它的兄弟元素跟它的標籤一樣,這時候無法通過層級定位到。因為都是一個父親生的,多胞胎兄弟。
  2. 雖然雙胞胎兄弟很難識別,但是出生是有先後的,於是可以通過它在家裡的排行老幾定位到。
  3. 如下圖四胞胎兄弟,可以用XPath定位老大、老二和老三(這裡索引是從1開始算起的,跟Python的索引不一樣)

image

示例

定位上圖程式碼中的指定input標籤。

"""
1.學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        相對路徑:索引定位元素
        //父標籤名[@父標籤屬性名='屬性值']/子標籤[索引值]   索引從1開始
3.需求
    頁面中使用XPath索引定位input標籤
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟頁面
url = "file:///" + os.path.abspath("./練習頁面/Test_Xpath.html")
driver.get(url)

# 4.使用xpath索引定位元素
# 定位第一個input標籤
# 如果是第一個元素,索引值可以不加。因為不加索引值會選取form下的全部input標籤
# 而我們用的是單數定位形式,預設選擇第一個。
input_1 = driver.find_element_by_xpath("//form[@id='formID']/input")
print("第一個input標籤", input_1.get_attribute("outerHTML"))
# 定位第三個input標籤
input_3 = driver.find_element_by_xpath("//form[@id='formID']/input[3]")
print("第三個input標籤", input_3.get_attribute("outerHTML"))

# 5.關閉瀏覽器
sleep(2)
driver.quit()

"""
輸出結果:
第一個input標籤 <input type="text" name="name1" class="test">
第三個input標籤 <input type="submit" name="1_name_3" value="cn">
"""

(5)XPath邏輯定位

在頁面元素定位過程中,會出現有一些元素擁有相同的屬性和屬性值,這個時候就沒有辦法用一個屬性來通過XPath進行定位了。這個時候就需要用多個屬性去定位,這就是XPath邏輯定位。

XPath邏輯定位說明:

  1. XPath還有一個比較強的功能,可以支援與(and)、或(or)、非(not)。
  2. 一般用的比較多的是and運算,同時滿足兩個屬性。

需求:在下面程式碼片段中,使用XPath邏輯定位test2標籤。

<body>
    <p id="login_user">
        <label for="">test1:</label>
        <input type="text"  name="user" class="login"/>
    </p>
    <p id="login_user">
        <label for="">test2:</label>
        <input type="text" name="user" class="login-test"/>
    </p>
</body>

示例

"""
1.學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        相對路徑:邏輯定位
        //標籤名[@屬性名1='屬性值1'and@屬性名2=屬性值2]
        使用多屬性定位元素
3.需求
    在頁面中使用XPath邏輯定位test2標籤
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟頁面
url = "file:///" + os.path.abspath("./練習頁面/xpath.html")
driver.get(url)

# 4.定位test2輸入框使用XPath邏輯定位
test2 = driver.find_element_by_xpath("//input[@type='text'and@name='user'and@class='login-test']")
print(test2.get_attribute("outerHTML"))

# 5.關閉瀏覽器
sleep(2)
driver.quit()

"""
輸出結果:
<input type="text" name="user" class="login-test">
"""

(6)XPath模糊匹配定位

有些標籤元素的屬性值太長,我們就可以模糊匹配的定位方式來定位目標元素。

掌握了模糊匹配功能,基本上沒有定位不到的元素。

需求:定位下面程式碼片段中的指定元素。

<bookstore id='zc'>
    <book id='b1'>
        <title lang="eng">Harry Potter</title>
        <price>29.99</price>
    </book>

    <book id='b2'>
        <title lang="eng" id="t2">Learning XML</title>
        <price>39.95</price>
    </book>
    <p>
        <book id='b3'>
            <title lang="eng" id="t3">Learning HTML</title>
            <price>99.95</price>
        </book>
    </p>
</bookstore>

示例

"""
1..學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        相對路徑:模糊查詢
        (1)* : 匹配任何元素節點。
        (2)@* : 匹配任何屬性節點。
        (3)node() : 匹配任何型別的節點。
3.需求
    在頁面中使用xpath的模糊匹配定位目標元素
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟註冊A頁面
url = "file:///" + os.path.abspath("./2.html")
driver.get(url)
sleep(2)

# 4.XPath模糊定位
# 4.1 選取 bookstore 元素的所有子元素。
element_1 = driver.find_elements_by_xpath("//bookstore/*")
for element in element_1:
    print(element.get_attribute("outerHTML"))

# 4.2 匹配絕對路徑最外層元素
element_2 = driver.find_element_by_xpath("/*")
print(element_2.get_attribute("outerHTML"))

# 4.3 選取頁面中的所有元素。
element_3 = driver.find_element_by_xpath("//*")
print(element_3.get_attribute("outerHTML"))

# 4.4 選取所有帶有屬性的 title 元素。
element_4 = driver.find_element_by_xpath("//title[@*]")
print(element_4.get_attribute("outerHTML"))

# 4.5 匹配所有有屬性的節點(屬性模糊查詢使用很少)。
element_5 = driver.find_element_by_xpath("//*[@*]")
print(element_5.get_attribute("outerHTML"))

# 4.6 匹配bookstore節點所有孫子輩的id屬性值為t2的title節點
textA = driver.find_element_by_xpath("//bookstore/node()/title[@id='t2']")
print(textA.get_attribute("outerHTML"))

# 5.關閉瀏覽器
driver.quit()

(7)XPath其他定位方式

程式碼片段如下:

<html>
    <body>
        <ul>
            <li>咖啡</li>
            <li>茶</li>
            <li>牛奶</li>
                <a rel="milk" href="http://10.106,17.69:8081/food/index.php?m=usc=loginsa=order">
                    訂餐
                </a>
        </ul>
    </body>
</html>

1)contains

contains關鍵字,是用於模糊查詢定位,意思是屬性中含有xxx的元素。

內容匹配可以是部分內容,也可以是全部內容。

需求:定位上面程式碼片段中的<a>標籤。

說明:

  • 這段程式碼中的“訂餐”這個超連結,沒有標準id元素,只有一個relhref,不是很好定位。可以使用XPath的模糊匹配模式來定位它。
  • 尋找頁面中href屬性值包含有order這個單詞的所有a元素,由於這個“訂餐”按鈕的href屬性裡肯定會包含order,所以這種方式是可行的,也會經常用到。其中@後面可以跟該元素任意的屬性名。

示例:

"""
1..學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        相對路徑:模糊查詢定位
        需要使用contains關鍵字(包含)
        格式://標籤名[contains(@屬性名,部分屬性值)]
        應用:一般適用於id,name,class是動態的情況下
3.需求
    在頁面中使用XPath的模糊匹配定位<a>標籤
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟頁面
url = "file:///" + os.path.abspath("./123.html")
driver.get(url)

# 4.使用xpath模糊匹配,使用contains
button = driver.find_element_by_xpath("//a[contains(@href, 'order')]")
print(button.get_attribute("outerHTML"))

# 5.關閉瀏覽器
sleep(2)
driver.quit()

2)starts-with

搜尋元素屬性值以什麼開頭進行模糊定位。

示例

# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟頁面
url = "file:///" + os.path.abspath("./123.html")
driver.get(url)

# 4.使用xpath模糊匹配,使用starts-with
"""
尋找rel屬性以mi開頭的a元素。
其中@後面的rel可以替換成元素的任意其他屬性。
"""
button = driver.find_element_by_xpath("//a[starts-with(@rel, 'mi')]")
print(button.get_attribute("outerHTML"))

# 5.關閉瀏覽器
sleep(2)
driver.quit()

3)Text

直接查詢頁面中所有的“茶”字,根本就不用知道它是個<li>元素。這種方法也經常用於純文字的查詢。

示例:

# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟註冊A頁面
url = "file:///" + os.path.abspath("./123.html")
driver.get(url)

# 4.xpath定位,使用text方法
button = driver.find_element_by_xpath("//*[text()='茶']")
print(button.get_attribute("outerHTML"))

# 5.關閉瀏覽器
sleep(2)
driver.quit()

"""
輸出結果:
<li>茶</li>
"""

4)|連結符

通過在路徑表示式中使用|運算子,可以選取若干路徑中所匹配標籤的結果集。

例如:

  • //p|//*[@id="fun"] :表示將選擇所有pid="fun"的標籤元素。
  • //a|//p|//div:表示將選擇所有apdiv標籤元素。

示例

"""
1..學習目標:
    必須掌握selenium中XPath定位方法
2.語法
    2.1 selenium中語法
        driver.find_element_by_xpath("XPath表示式")
    2.2 XPath表示式
        相對路徑:| 連結符用法
        通過在路徑表示式中使用 | 運算子,可以選取若干路徑中所匹配標籤的結果集。

3.需求
    在頁面中使用xpath的 | 連結符,匹配定位目標元素
"""
# 1.匯入selenium
from selenium import webdriver
from time import sleep
import os

# 2.開啟瀏覽器
driver = webdriver.Chrome()

# 3.開啟註冊A頁面
url = "file:///" + os.path.abspath("./123.html")
driver.get(url)
sleep(2)

# 4.XPath中 | 連結符 定位
# 4.1 選取茶所在的<li>標籤和<a>標籤
element_1 = driver.find_elements_by_xpath("//li[last()-1] | //a")
for element in element_1:
    print(element.get_attribute("outerHTML"))


# 5.關閉瀏覽器
driver.quit()

"""
輸出結果:
<li>茶</li>
<a rel="milk" href="http://10.106,17.69:8081/food/index.php?m=usc=loginsa=order">
    訂餐
</a>
"""

2、總結:

這裡指做了一些最常用的XPath定位方式的練習。如果在工作中有需要用到一些特別的用法,可以檢視XPath的文件。

提示:XPath的文件地址:http://www.w3school.com.cn/xpath/index.asp

相關文章