被測試網頁的HTML代碼
<html> <body> <div id="div1" style="text-align:center"> <img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png" href="http://www.sogou.com">sogou image</img><br /> <input name="div1input"> <a href="http://www.sogou.com">搜狗搜索</a> <input type="button" value="查詢"> </div> <br> <div id="div2" style="text-align:center"> <img alt="div2-img2" src="http://www.baidu.com/img/bdlogo.png" href="http://www.baidu.com">baidu image</img><br /> <input name="div2input"> <a href="http://www.baidu.com">百度搜索</a> <input type="button" value="查詢"> </div> </body> </html>
使用上面的代碼生成被測試網頁,基於此網頁來實現各種不同的頁面元素的xpath定位方法
①xpath絕對路徑定位元素
絕對路徑表示頁面元素在被測網頁的HTML代碼結構中,從根節點一層層地搜索到需要被定位的頁面元素,絕對路徑起始於正斜杠(/),每一步均被斜杠分割。
目的
在被測網頁中查找第一個div標簽下的“查詢”按鈕
xpath定位表達式:
/html/body/div/input[@value="查詢"]
python定位語句:
element = driver.find_element_by_xpath('/html/body/div/input[@value="查詢"]')
代碼解釋
上述xpath定位表達式從html dom樹的根節點(html節點)開始逐層查找,最后定位到“查詢”按鈕節點。路徑表達式“/”表示跟節點。
使用絕對路徑定位頁面元素的好處在於可以驗證頁面是否發生變化。如果頁面結構發生變化,可以會造成原先有效的xpath表達式失敗。使用絕對歷經定位是十分脆弱的,因為即便頁面代碼結構只發生了微小的變化,也可能會造成原先有效的xpath定位表達式定位失敗。因此,建議在自動化測試的定位實施環節中,優先考錄使用后面將要介紹的相對路徑進行定位。
②xpath相對路徑定位元素
相對路徑的每一步都根據當前節點集之中的節點來進行計算,起始於雙//。
目的
在被測試網頁中,查找第一個div標簽下的“查詢”按鈕。
xpath定位表達式:
//div[@value='查詢']
python定位語句:
element = driver.find_element_by_xpath('//div[@value='查詢']')
代碼解釋
上述xpath定位表達式中//表示從匹配選擇的當前節點開始選擇文檔中的節點,而不考慮特面的位置。input[@value="查詢"]表示定位value值為“查詢”兩個字的input頁面元素。
相對路徑的xpath定位表達式更加簡潔,不管頁面發生了何種變化,只要input標簽的value屬性值沒變,始終都可以定位到。推薦使用相對路徑的xpath表達式,並且越簡潔越好,可大大降低測試腳本中定位表達式的維護成本。
③xpath使用索引號定位元素
索引號表示某個被定位的頁面元素在其父元素節點下的同名元素中的位置符號,需要從1開始。
目的
在被測網頁中,查找第一個div標簽下的“查詢”按鈕
xpath定位表達式:
//input[1]
python定位語句:
element=driver.find_element_by_xpath("//input[1]")
代碼解釋
索引號定位方式是根據該頁面元素在頁面中相同標簽名之間出現的索引位置來進行定位。上述xpath定位表達式表示查找頁面中第二個出現的input元素,即被測試頁面上的“查詢”按鈕。
若在Firefox瀏覽器的插件(try xpath,新版本的firepath已經沒有了!真的挺傷心的)中使用上述的定位方式你會發現定位到兩個元素,兩個div標簽下的input都被定位到了,這和只查找第一個input元素相沖突,這是由於被測網頁中兩個div標簽都包含了input標簽,xpath再查找的時候把每個div節點都當作相同的起始層級開始查找,所以用//input[1]表達式會同時查找到兩個div節點下的第一個input元素。如果再兩div標簽下還有嵌套的div,並且嵌套的div下也有input標簽,也會被定位到。因此在使用索引號定位頁面元素的時候,需要注意網頁html代碼中是否包含了多個層級完全相同的代碼結構,若出現了這種情況,就需要修改定位表達式,以確保自動化測試腳本中使用的定位表達式能唯一定位所需要的元素。如果想同時定位多個相同的input頁面元素可以使用下面的python語句:
elementList=driver.find_elements_by_xpath("//input[1]")
將定位的多個元素存儲到list中,然后根據list索引號獲取想要的頁面元素。但如果發現頁面元素會經常增加或減少,就不建議使用索引號定位方式。
基於實例中的被測網頁,下面給出更多的通過索引號定位的實例
| 預期定位圓面的元素 | 定位表達式實例 | 使用的屬性值 |
| 定位第二個div下的超鏈接 | //div[last()]/a | div[last()]表示最后一個div元素,last()函數獲取的是指定元素的最后的索引號 |
| 定位第一個div中的超鏈接 | //div[last()-1]/a | div[last()-1]表示倒數第二個div元素 |
| 定位最前面一個屬於div元素的子元素中的input元素 | //div/input[position()<2] | position()函數獲取當前元素input的位置序號 |
④xpath使用頁面元素的屬性值定位元素
在定位頁面元素的時候 ,經常會遇到各種復雜的結構的被測試網頁,並且很多頁面元素也沒有設計ID,Name等屬性,同時又不想使用絕對路徑或索引號來定位頁面元素,但是發現要被要被定位的頁面元素擁有某些固定不變的屬性及屬性值,此時推薦屬性定位方式來定位頁面元素。
目的
定位被測網頁中的第一張img元素
xpath定位表達式:
//input[@alt='div1-img1']
python定位語句:
img = driver.find_element_by_xpath("//input[@alt='div1-img1']")
代碼解釋
表達式使用了相對路徑再結合元素擁有的特定屬性方法進行定位,定位元素img的屬性是“alt”,值為“div1-img1”,使用@符號指明后面接的是屬性,並同屬性及屬性值一起寫到元素后的方括號中。
被測試網頁的元素通常會包含各種各樣的屬性值,並且很多屬性值具有唯一性。若能確認屬性值不常變並且唯一,強烈建議使用相對路徑再結合屬性的定位方式來編寫xpath定位方式,使用此方法可以解決99%的頁面元素定位問題。下面給出更多的定位實例。
| 預定位的頁面元素 | 定位表達式實例 | 使用的屬性值 |
| 定位頁面的第一張圖片 | //img[@href=""http://www.sogou.com] | 使用img標簽的屬性href值 |
| 定位第二個div中第一個input輸入框 | //div[@id="div2"]/input[@name="div2input"]或者//inuput[@name="div2input"] | 使用div變遷的name值 使用input標簽的name屬性值 |
| 定位第一個div中的第一個鏈接 | //div[@id="div1"]/a[@href="http://www.sogou.com"] | 使用div標簽的ID屬性值 使用a標簽的href屬性值 |
| 定位頁面的查詢按鈕 | //input[@type="button"] | 使用input標簽的type屬性值 |
⑤xpath使用模糊屬性值定位元素
模糊屬性值定位方式表示使用屬性值的一部分內容定位。在自動化測試的實施過程中,常常會遇到頁面元素的屬性值是動態生成的,也就是說每次訪問屬性值都不一樣,此類頁面元素會加大定位難度,使用模糊屬性值定位方式可以解決一部分類似難題,但前提是屬性值中有一部分內容是不變的,xpath提供了一些可以實現模糊屬性值的定位需求的函數。
| xpath函數 | 定位表達式實例 | 表達式解釋 |
| starts-with(str1,str2) | //img[starts-with(@alt,"div1")] | 查找屬性alt的屬性值以div1關鍵字開始的頁面元素 |
| contains(str1,str2) | //img[contains(@alt,"img")] | 查找alt屬性的屬性值包含img關鍵字的頁面元素,只要包含即可,無需考慮位置 |
contains函數屬於xpath的高級用法,使用場景比較多,盡管頁面元素的屬性值經常變化,但只要其屬性值有幾個固定不變的關鍵詞,就可以使用cotains函數進行定位。
⑥xpath使用xpath軸定位元素
軸可以定義相對於當前節點的節點集。使用xpath定位方式可以根據再文檔樹中的元素相對位置關系進行頁面元素定位。先找到一個相對好定位的元素,讓它作為軸,根據它和要定位元素間的相對位置關系進行定位,可解決一些點定位難的問題。
我們根據被測頁面的代碼來畫一下結構圖:

xpath常用軸關鍵字:
| xpath軸關鍵字 | 軸的含義說明 | 定位表達式實例 | 表達式解釋 |
| parent | 選擇定錢節點的上一層父節點 | //img[@alt='div2-img2']/parent::div | 查找到屬性alt的屬性值為div2-img2的img元素,並基於該img元素的位置找到它上一級的div頁面元素 |
| child | 選擇當前節點的下層所有子節點 | //div[@id='div1']/child::img | 查找到ID屬性值為div1的div元素,並基於div的位置找到它下層節點中的img頁面元素 |
| ancestor | 選擇當前節點所有上層節點 | //img[@alt='div2-img2']/ancestor::div | 查找到屬性alt的屬性值為div2-img2的img元素,並基於該img元素的位置找到它上級的div元素 |
| descendant | 選擇當前節點所有下層的節點(子,孫等) | //div[@name='div2']/descendant::img | 查找到屬性name的屬性值為div2的div元素,並基於該元素的位置找到它下級所有節點中的img頁面元素 |
| following | 選擇當前節點之后顯示的所有節點 | //div[@id='div1']/following::img | 查找到ID屬性值為div1的div頁面元素,並基於div的位置找到它后面節點中的img頁面元素 |
| following-sibling | 選擇當前節點后續所有兄弟節點 | //a[@href='http://www.sogou.com']/following-sibling::input | 查找到鏈接地址為http://www.sogou.com的鏈接頁面元素a,並基於鏈接的位置找到它后續兄弟節點中的input頁面元素 |
| preceding | 選擇當前節點前面的所有節點 | //img[@alt='div2-img2']/preceding::div | 查找到屬性alt的屬性值為div2-img2的圖片頁面元素img,並基於圖片的位置找到它前面節點中的div頁面元素 |
| preceding-sibling | 選擇當前節點前面的 所有兄弟節點 | //input[@value='查詢']/preceding-sibling::a[1] | 查找到value屬性值為“查詢”的輸入框頁面元素,並基於該輸入框的位置找到他前面同級節點中的第一個鏈接頁面元素 |
有時候我們會再軸后面加一個星號*, 便是通配符,如://input[@value="查詢"]/preceding::*,它表示查找屬性value的值為“查詢”的輸入框input元素前面所有的同級元素,但不包括input元素本身
⑦xpath使用頁面元素的文本定位元素
通過text()函數可以定位到元素文本包含某些關鍵內容的頁面元素。
xpath表達式:
1.//a[text()="搜狗搜索"] 2.//a[.="搜狗搜索"] 3.//a[contains(.,"百度")] 4.//a[contains(text(),'百度')] 5.//a[contains(text(),"百度")]/preceding::div 6.//a[contains(. , "百度")]/..
python定位語句:
sogou_a=driver.find_element_by_xpath('//a[text()="搜狗搜索"]') sogou_a=driver.find_element_by_xpath('//a[.="搜狗搜索"]') baidu_a=driver.find_element_by_xpath('//a[contains(.,"百度")]') baidu_a=driver.find_element_by_xpath('//a[contains(text(),'百度')]') div=driver.find_element_by_xpath('//a[contains(text(),"百度")]/preceding::div') div=driver.find_element_by_xpath('//a[contains(. , "百度")]/..')
代碼解釋
xpath表達式1和表達式2等價,都是查找文本內容為“搜狗搜索”的鏈接頁面元素,使用的是精准匹配方式,也就是說文本內容必須完全匹配,不能多一個字也不能少一個字。第二個xpath語句中使用了以個點. 這里的點等價於text(),都指代的是當前節點的文本內容
xpath表達式3和表達式4等價,都是查找文本內容包含“百度”關鍵字的鏈接頁面元素,使用的是模糊匹配方式,即可以根據部分文本關鍵字進行匹配。
xpath表達式5和表達式6等價,都是查找文本內容包含“百度”關鍵字的鏈接頁面元素a的上層父元素div,6最后使用了兩個點。。,它表示選取當前節點的父節點,等價於preceding::div。
使用文本內容匹配模式進行定位,為定位復雜元素又提供了一種強大的定位模式,再遇到定位困難時,可以優先考慮使用此方式進行定位。建議大家對此定位方式進行練習,一邊做到隨意定位頁面的任意元素。
總結
好了,以上差不多就時xpath所有的定位方式了,大家可以根據實際工作中遇到的不同問題選擇不同的定位方式。 如果文中有錯誤請留言指出,大家一起學習一起進步,歡迎多多指教!最后再說一句,實踐出真知,多看多學多練多寫,沒有誰出生就是大牛,得經過漫長的歲月慢慢擠奶才變成大牛!哈哈
