前情提示:在前一篇文章中,我們詳細的介紹了XPath路徑表示式的使用方式。那麼本篇文章我們就來說說在Selenium測試框架中如何使用XPath定位元素。
XPath定位和Selenium基礎元素定位方式一樣,都可以獲取單個元素或者多個元素的結果集。
如下所示:
- 單數定位,獲得一個指定元素物件:
driver.find_element_by_xpath("XPath路徑表示式")
- 複數定位,獲得指定元素結果集列表:
driver.find_elements_by_xpath("XPath路徑表示式")
1、Selenium中使用XPath查詢元素
(1)XPath通過id
,name
,class
屬性定位
"""
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">
"""
總結
- 如果不想制定標籤名稱,可以用
*
號表示任意標籤。- 有時候同一個屬性,同名的比較多,這時候可以通過標籤篩選下,定位更準一點。
- 如果想制定具體某個標籤,就可以直接寫標籤名稱。
(2)XPath通過標籤中的其他屬性定位
如果一個元素id
,name
,class
屬性都沒有,這時候也可以通過其它屬性定位到。
# 需求:使用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層級定位
- 如果一個元素,它的屬性不是很明顯,無法直接定位到,這時候我們可以先找它老爸(父元素)。
- 找到它老爸後,再找下個層級就能定位到了。
- 如下圖圖所示,要定位的是
input
這個標籤,它的老爸的class=’s_ipt_wr‘
。 - 要是它老爸的屬性也不是很明顯,就找它爺爺
id=form
。 - 於是就可以通過層級關係定位到。
示例:
需求:在頁面中,定位下面程式碼片段中的<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索引定位
- 如果一個元素它的兄弟元素跟它的標籤一樣,這時候無法通過層級定位到。因為都是一個父親生的,多胞胎兄弟。
- 雖然雙胞胎兄弟很難識別,但是出生是有先後的,於是可以通過它在家裡的排行老幾定位到。
- 如下圖四胞胎兄弟,可以用XPath定位老大、老二和老三(這裡索引是從1開始算起的,跟Python的索引不一樣)
示例:
定位上圖程式碼中的指定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邏輯定位說明:
- XPath還有一個比較強的功能,可以支援與(
and
)、或(or
)、非(not
)。 - 一般用的比較多的是
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
元素,只有一個rel
和href
,不是很好定位。可以使用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"]
:表示將選擇所有p
和id="fun"
的標籤元素。//a|//p|//div
:表示將選擇所有a
,p
與div
標籤元素。
示例:
"""
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。