前情提示:在前一篇文章中,我們詳細的介紹了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。