前言
CSS定位方式和XPATH定位方式基本相同,只是CSS定位表達式有其自己的格式。CSS定位方式擁有比XPATH定位速度快,且比XPATH穩定的特性。下面詳細介紹CSS定位方式的使用方法
被測網頁的HTML代碼
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style type="text/css"> input.spread { Font-SIZE:20pt;} input.tight { FONT-SIZE:10pt;} </style> </head> <body onload="document.getElementById('div1input').focus()"> <div id="div1" style="text-align:center"> <input id="div1input" class="spread"/></input> <a href="http://www.sogou.com">搜狗搜索</a> <img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png" href="http://www.sogou.com">搜狗圖片</img> <input type="button" value="查詢"></input> </div> <br> <p>第一段文字</p> <p>第二段文字</p> <div name= "div2" style="text-align:center"> <input name="div2input" class="tight"></input> <a href="http://www.baid.com">百度搜索</a> <img alt="div2-img2" src="http://www.baidu.com/img/bdlogo.png" href="http://www.baidu.com">百度圖片</img> <input type="button" value="查詢"></input> </div> <div class="foodDiv"> <ul id="recordlist"> <p>土豆</p> <li>西紅柿</li> </ul> </div> </body> </html>
①使用絕對路徑定位元素
目的
在被測試網頁中,查找第一個div中的查詢按鈕
CSS定位方式:
html > body > div >input[value="查詢"]
Python定位語句:
element = driver.find_element_by_css_selector('html > body > div >input[value="查詢"]')
代碼解釋:
上述CSS定位表達式使用絕對路徑定位屬性value的值為“查詢”的頁面元素。從CSS定位表達式可以看出,步間通過“>"分割,區別於XPATH路徑中的正”/“,並且也不再使用@符號選擇屬性。
②使用相對路徑定位元素
目的
在被測試網頁中,查找第一個div下的查詢按鈕
CSS定位表達式:
input[value="查詢"]
Python定位語句:
element = driver.find_element_by_css_selector('input[value="查詢"]')
代碼解釋
上述CSS表達式通過相對路徑使用元素名稱和元素的屬性及屬性值進行頁面元素的定位。
③使用class名稱定位元素
目的
在被測網頁中,查找第一個div元素下的input輸入框
CSS定位表達式:
css.spread
python定位語句:
element = driver.find_element_by_css_selector('css.spread')
代碼解釋
上述CSS定位表達式使用input頁面元素的class屬性名稱spread來進行定位,用點(.)分割元素名與class屬性名,點號后面是class屬性名稱
④使用ID屬性值定位元素
目的
在被測試網頁中,查找第一個dic元素下ID屬性值為div1input“的input元素
CSS定位語句:
input#div1input
Python定位語句:
element = driver.find_element_by_css_selector('input#div1input')
代碼解釋
上述CSS定位表達式使用input頁面元素的ID屬性值div1input進行定位,使用#號分割元素名和ID屬性值,#后面是ID屬性值
⑤使用頁面其他屬性值定位元素
目的
在被測網頁中,查找div元素下的第一張圖片元素img
CSS定位表達式:
img[alt="div1-img1"] img[alt="div1-img1"][href="http://www.sogou.com"]
Python定位語句:
element = driver.find_element_by_css_selector('img[alt="div1-img1"]') element = driver.find_element_by_css_selector('img[alt="div1-img1"][href="http://www.sogou.com"]')
代碼解釋:
表達式1和表達式2是等價的,都是定位第一個img元素
表達式1:表示使用img頁面元素的alt元素的屬性值div1-img1進行定位。若定位的頁面元素始終具有唯一的屬性值,此定位方式可以解決很多頻繁變動的頁面元素
表達式2:表示同時使用了img頁面元素的alt和href屬性進行頁面元素的定位。在某些復雜的定位場景,可使用多個屬性來確保定位元素的唯一性。
⑥使用屬性值的一部分內容定位元素
目的
在被測試網頁中,查找“搜狗搜索”鏈接
CSS定位表達式:
1 a[href^="http://www.so"] 2 a[href$="gou.com"] 3 a[href*="sogou"]
Python定位語句:
1 element = driver.find_element_by_css_selector('a[href^="http://www.so"]') 2 element = driver.find_element_by_css_selector('a[href$="gou.com"]') 3 element = driver.find_element_by_css_selector('a[href*="sogou"]')
代碼解釋
1.表示匹配鏈接地址開始為http://www.so關鍵字串的鏈接元素,以字符^指明從字符串的開始匹配
2.表示匹配鏈接地址結尾包含gou.com關鍵字串的鏈接元素,以字符$指明在字符串的結尾匹配
3.表示匹配鏈接地址包含sogou關鍵字串的鏈接元素,以字符*指明在需要進行模糊查詢
使用此模糊定位方式,可匹配動態變化的屬性值的頁面元素,只要找到屬性值固定不變的關鍵部分,就可以進行模糊匹配定位。此方法可以解決大部分復雜定位的問題,當然無論是方式都需要靈活使用才能確保能夠准確的定位都想要定位的元素
⑦使用頁面元素進行子頁面元素的查找
目的
在被測網頁中,查找第一個div下的第一個input元素
CSS定位表達式:
1 div#div1>input#div1input 2 div input
Python定位語句:
1 element=driver.find_element_by_css_selector("div#div1>input#div1input") 2 element=driver.find_elements_by_css_selector("div input")
代碼解釋
1.表達式1中的div#div1,表示在被測試網頁上定位到ID屬性值為div1的div頁面元素,> 表示在以查找到的div元素的子頁面元素中進行查找,input#div1input表示查找ID屬性值為div1input的input頁面元素,此方法可實現查找div下子頁面元素的辦法
2.表達式2表示匹配所有屬於div元素后代的input元素,表達式中父元素div和子元素input中間需用空格分割,注意此表達式是定位一組input元素,並不是單個input元素
⑧使用偽類定位元素
目的
在被測試網頁中查找第一個div下的指定子頁面元素
CSS定位表達式:
1 div#div1 :first-child 2 div#div1 :nth-child(2) 3 div#div1 :last-child 4 input:focus 5 input:enabled 6 input:checked 7 input:not([id])
Python定位語句:
1 element=driver.find_element_by_css_selector("div#div1 :first-child")
2 element=driver.find_element_by_css_selector("div#div1 :nth-child(2)")
3 element=driver.find_element_by_css_selector("div#div1 :last-child")
4 element=driver.find_element_by_css_selector("input:focus")
5 element=driver.find_elements_by_css_selector("input:enabled")
6 element=driver.find_elements_by_css_selector("input:checked")
7 element=driver.find_elements_by_css_selector("input:not([id])")
代碼解釋
偽類表達式是CSS語法支持的定位方式,前3個表達式特別注意的是在冒號前一定要有一個空格,否則定位不到想要定位的元素
1.表達式1表示查找ID屬性值為div1的div頁面元素下的第一個子元素,根據被測試網頁定位的是div下的input元素,first-child表示查找某個頁面元素下的第一個子頁面元素
2.表達式2表示查找ID屬性值為div1的div頁面元素下的第二個子元素,參照被測網頁,定位到的頁面元素是一個鏈接元素
3.表達式3表示查找ID屬性值為div1的div頁面元素下的最后一個子元素,根據被測試網頁定位的是一個按鈕元素;last-child表示的是查找某個頁面元素下的最后一個子頁面元素
4.表達式4 表示查找當前獲取焦點的input頁面元素
5.表達式5表示查找可操作的input元素
6.表示查找處於勾選狀態的checkbox頁面元素
7.表示查找所有無id屬性的input頁面元素
⑨查找同級兄弟頁面元素
目的
在被測試網頁中,查找第一個div下第一個input子頁面元素同級兄弟頁面元素
CSS定位表達式:
1 div1#div1 > input + a 2 div1#div1 > input + a + img 3 div1#div1 > input + * + img 4 ul#recordlist > p~li
Python定位語句:
1 element=driver.find_element_by_css_selector("div1#div1 > input + a") 2 element=driver.find_element_by_css_selector("div1#div1 > input + a + img") 3 element=driver.find_element_by_css_selector("div1#div1 > input + * + img")
4 element=driver.find_elements_by_css_selector("ul#recordlist > p~li")
代碼解釋
1.表達式1表示在ID屬性值為div1的頁面元素下,查找input頁面元素后的同級的且相鄰的鏈接元素a
2.表達式2表示在ID屬性值為div1的頁面元素下,查找input元素和鏈接元素a后面相鄰的圖片元素img
3.表達式3表示在ID屬性值為div1的頁面元素下,創造找input頁面元素和任意一種頁面元素后面的同級且相鄰的圖片元素img,* 表示任意類型的一個頁面元素,只能表示一個元素,如果想用此方法查找第一個div下的最后一個input元素,表達式寫法為div#div1 > input + * + * + input或div#div1 > input + a + * + input或div#div1 > input + a + img + input
4.表達式4表示ID屬性值為recordlist的ul頁面元素下,查找p頁面元素以后所有的li元素
⑩多元素選擇器
CSS定位表達式支持多元素選擇器,也就是一次可以同時選擇多個相同的標簽,也可以同時選擇多個不同的標簽,不同標簽間用英文的逗號隔開
目的
在被測網頁中,同時選擇多個不同的頁面元素
CSS定位表達式:
div#div1,input,a
Python定位語句:
element=find_elements_by_css_selector("div#div1,input,a')
代碼解釋
上面的css表達式表示同時查找所有ID屬性值為div1的div元素,所有的input元素,所有的a元素
總結
目前為止,已經整理了自動化測試Python+Selenium中對於web測試定位頁面元素的兩種主流,也是最好的定位方式XPATH和CSS定位方式,在我個人看來兩個方式都很不錯,效率都很高,也很容易解決日常工作中的問題,也能夠減少頁面的變動對於腳本的維護成本,當然不同問題還需要不同的方式解決,能解決問題的方法都是好方法,希望以后的日子對於定位元素不再是難題。下面我們對這兩種定位方式大概做個對比;
XPATH定位和CSS定位很相似,XPATH功能更強大一些吧,但CSS定位方式執行速度更快,鑒於某些瀏覽器不支持CSS定位方式,並且一般在自動化測試實施過程中使用xpath定位方式要比css更普遍,所以建議大家先掌握xpath,再來看下二者在語法上有什么區別
| 定位元素目標 | XPATH | CSS |
| 所有元素 | //* | * |
| 所有div元素 | //div | div |
| 所有div元素子元素 | //div/* | div>* |
| 根據ID屬性獲取元素 | //*[@id=''] | div#id |
| 根據class屬性獲取元素 | //*[@class=''] | div.class |
| 擁有某個屬性的元素 | //*[@href=''] | *[href=''] |
| 所有div元素的第一個子元素 | //div/*[1] | div>* :first-child |
| 所有擁有子元素a的div元素 | //div[a] | 無法實現 |
| input的下一個兄弟元素 | //input/following-sibling::[1] | input+* |
