selenium之元素定位-xpath
被測試網頁的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所有的定位方式了,大家可以根據實際工作中遇到的不同問題選擇不同的定位方式。 如果文中有錯誤請留言指出,大家一起學習一起進步,歡迎多多指教!最後再說一句,實踐出真知,多看多學多練多寫,沒有誰出生就是大牛,得經過漫長的歲月慢慢擠奶才變成大牛!哈哈