CSS Selector和Xpath均可以用來表示XML文檔中的位置。CSS (Cascading Style Sheets)是一種樣式表語言,是全部瀏覽器內置的,用於描述以HTML或XML編寫的文檔的外觀和樣式。CSS Selector用於選擇樣式化的元素,因此理論上前端人員能夠定位 DOM 節點並設置樣式,那麼對於測試人員這些元素也能夠定位到。css
XPath是XML路徑語言,是一種查詢語言,使用路徑表達式瀏覽XML文檔中的元素和屬性。XPath標準語法以下:html
Xpath=//tagname[@attribute='value']前端
XPath有絕對定位和相對定位兩種,絕對定位使用絕對路徑,缺點是路徑太長,只要一個節點變更就沒法定位。以單斜槓(/)開始,表示從根節點開始選擇元素。下面是頁面https://www.baidu.com/上「百度一下」按鈕的絕對路徑:python
/html/body/div[1]/div[1]/div[5]/div[1]/div/form/span[2]/input
相對路徑以雙斜槓(//)開始,能夠從HTML文檔的任何位置開始,「百度一下」按鈕的相對路徑能夠表示以下git
//input[@id="su"]
CSS Selector和Xpath幾乎能夠定位到全部Web元素(HTML和XML文檔元素,Android應用的層級結構使用xml編寫),它們的主要差別包括:web
接下來對比一下這兩種方法的語法差別,節點的定義咱們規定以下:瀏覽器
xpath使用‘/’,CSS Selector使用‘>’post
Xpath | CSS Selector | |
---|---|---|
語法 | //element/element | element>element |
示例 | //div/a | div > a |
描述 | 選擇父元素爲 <div> 元素的全部 <a> 元素。 |
還可使用XPath Axes(軸)child 來定位子元素性能
XPATH:測試
//div/child::* # 選擇父元素爲 <div> 元素的全部兒子元素 //div/child::a # 選擇父元素爲 <div> 元素的全部<a>元素
CSS Selector:
div > a:nth-child(2) # 選擇父元素爲 <div> 元素的第二個<a>元素 div > a:nth-last-child(2) # 選擇父元素爲 <div> 元素的倒數第二個<a>元素 div > a:last-child # 選擇父元素爲 <div> 元素的最後一個<a>元素 div > a:first-child # 選擇父元素爲 <div> 元素的第一個<a>元素
xpath使用‘//’,CSS Selector使用空格
Xpath | CSS Selector | |
---|---|---|
語法 | //element//element | element element |
示例 | //div//a | div a |
描述 | 選擇 <div> 元素內部的全部 <a> 元素。 |
還可使用XPath Axes(軸)descendant 來定位子孫元素
XPATH:
//div/descendant::* # 選擇祖先元素爲 <div> 元素的全部子孫元素 //div/descendant::a # 選擇祖先元素爲 <div> 元素的全部<a>元素
CSS Selector使用空格定位子孫元素後進行選擇:
div a:nth-child(2) # 選擇祖先元素爲 <div> 元素的第二個<a>元素 div a:nth-last-child(2) # 選擇祖先元素爲 <div> 元素的倒數第二個<a>元素 div a:last-child # 選擇祖先元素爲 <div> 元素的最後一個<a>元素 div a:first-child # 選擇祖先元素爲 <div> 元素的第一個<a>元素
在同一個父節點下,定位下一個相鄰節點
Xpath | CSS Selector | |
---|---|---|
語法 | //element/following-sibling::element | element + element |
示例 | //div/following-sibling::a | div + a |
描述 | 選擇緊接在 <div> 元素以後的全部 <p> 元素。 |
Xpath能夠定位當前節點前面的鄰居節點,CSS Selector不能
//*element/preceding-sibling::element
CSS Selector是前向的,不能利用子節點定位父節點
方法 | 描述 |
---|---|
.. | 一個點」.「表示選取當前節點,兩個點」..「表示選取當前節點的父節點。 |
ancestor | 當前節點祖先元素(父、祖父...) |
parent | 當前節點的父節點 |
Xpath | CSS Selector | |
---|---|---|
語法 | //*[@id='example'] | #example |
示例 | //*[@id='uesrname'] | #uesrname |
描述 | 選擇id='uesrname'的元素。 |
Xpath | CSS Selector | |
---|---|---|
語法 | //*[@class='example'] | .example |
示例 | //*[@class='uesrname'] | .uesrname |
描述 | 選擇class='uesrname'的元素。 |
沒有Id和Class的狀況下,可使用其它屬性值定位,好比name、type等。
Xpath | CSS Selector | |
---|---|---|
語法 | //*[@attribute='value'] | [attribute=value] |
示例 | //*[@name='uesrname'] | [name='username'] |
描述 | 選擇屬性值name='uesrname'的元素。 |
xpath可使用 ‘and’ 或者 ‘or’ 鏈接兩個屬性:
XPATH:
//input[@name='login'and @type='submit']
CSS Selector:
input[name='login'][type='submit']
CSS Selector能夠進行子字符串匹配進行定位:
^= 匹配前綴
[id^='id_prefix_'] # id前綴爲‘id_prefix_’的元素
$= 匹配後綴
[id$='_id_sufix'] # id後綴爲‘_id_sufix’的元素
*= 包含某個字符串
[id*='id_pattern'] # id包含‘id_pattern’的元素
Contains()方法也許經過部分文原本定位查找元素,CSS Selector不支持這種用法。
Xpath = //*[contains(@type,'partial_text')] Xpath = //*[contains(@name,'partial_text')] Xpath = //*[contains(@class,'partial_text')] Xpath = //*[contains(@id,'partial_text')] Xpath = //*[contains(text(),'partial_text')] Xpath = //*[contains(@href,'partial_text')]
查找屬性值以特定文本開始的元素
Xpath = //*[starts-with(@type,'start_text')] Xpath = //*[starts-with(@name,'start_text')] Xpath = //*[starts-with(@class,'start_text')] Xpath = //*[starts-with(@id,'start_text')] Xpath = //*[starts-with(text(),'start_text')] Xpath = //*[starts-with(@href,'start_text')]
Text()方法基於web元素文原本進行定位
Xpath = //*[text()='text_value']
百度一下」text「,點擊」資訊「
Xpath:
//*[@id="s_tab"]/descendant::a[1] //*[@id="s_tab"]/child::*[1]/a[1]
CSS selector:
#s_tab a:nth-child(2) #s_tab a:nth-last-child(9)
python測試代碼:
def test_css(self): self.driver.get("https://www.baidu.com/") self.driver.find_element_by_id("kw").send_keys("test") self.driver.find_element_by_id("su").click() # element = self.driver.find_element_by_css_selector("#s_tab a:nth-child(2)") # element = self.driver.find_element_by_css_selector('#s_tab a:nth-last-child(9)') element = self.driver.find_element_by_xpath('//*[@id="s_tab"]/descendant::a[1]') element.click() sleep(2)
點擊」資訊「下一個鄰居節點」視頻「
xpath
//*[@id="s_tab"]/descendant::a[1]/following-sibling::a[1] //*[@id="s_tab"]/child::*[1]/a[1]/following-sibling::a[1]
CSS selector:
#s_tab a:nth-child(2) + a #s_tab a:nth-last-child(9) + a
python測試代碼:
def test_css2(self): self.driver.get("https://www.baidu.com/") self.driver.find_element_by_id("kw").send_keys("test") self.driver.find_element_by_id("su").click() # element = self.driver.find_element_by_css_selector('#s_tab a:nth-child(2) + a') element = self.driver.find_element_by_xpath('//*@id="s_tab"]/descendant::a[1]/following-sibling::a[1]') element.click() sleep(2)
測試頁面:http://sahitest.com/demo/linkTest.htm
點擊」linkByContent「
xpath語法:
//*[contains(@href,"Content")] //*[starts-with(@href,"linkByC")] //*[contains(text(),"Content")] //*[text()="linkByContent"]
python測試代碼:
def test_css2(self): self.driver.get("http://sahitest.com/demo/linkTest.htm") # element = self.driver.find_element_by_xpath('//*[contains(@href,"Content")]') # element = self.driver.find_element_by_xpath('//*[starts-with(@href,"linkByC")]') # element = self.driver.find_element_by_xpath('//*[contains(text(),"Content")]') element = self.driver.find_element_by_xpath('//*[text()="linkByContent"]') element.click()
Xpath幾乎能夠定位到因此Web元素,CSS Selector效率更高,且代碼簡潔,但有些元素可能沒法定位,特別是須要經過子元素來定位的父元素,或者須要經過文本定位的元素。
在實際使用中,按照本身的實際狀況來選擇便可,CSS Selector理論上執行效率更高,但他們的性能差別不是很大,在幾毫秒或者幾十毫秒級別。這兩種定位方法除了本文介紹的之外,還有更多其它高級語法,能夠參考官方文檔。
文章標題:Web自動化測試:xpath & CSS Selector定位
本文做者:hiyo
本文連接:https://hiyong.gitee.io/posts/selenium-xpath-and-CSS-Selector-locator/ 歡迎關注公衆號:「測試開發小記」及時接收最新技術文章!