頁面元素定位 XPath 簡介
本文所說的 Xpath 是用於 Selenium 自動化測試所使用到的,是針對XHTML網頁而言的一種頁面元素的定位表示法。
XPath 背景
XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言。
XPath基於XML的樹狀結構,提供在數據結構樹中找尋節點的能力。起初XPath的提出的初衷是將其作為一個通用的、介於XPointer與XSL間的語法模型。但是XPath很快的被開發者采用來當作小型查詢語言。
若感興趣,可參考:https://zh.wikipedia.org/wiki/XPath ; 若不用 XML,僅需了解頁面元素 XPath,下文已足夠。
XPath 表示
在說明XPath元素表示法之前,需要對 HTML 語言有一定的了解,需了解 HTML的層級嵌套,html標簽,Tag Id 及 屬性值 等。
層級定位
若對HTML代碼較熟悉,則可猜測到上圖中該XPath是如何一層層定位下來的,其中如 div[2] 中 [2] 表示該層級結構下的第2個div
如果XPath的開頭是一個斜線(/)代表絕對路徑,元素存在一個或者不存在; 如果開頭是兩個斜線(//)代表相對路徑,表示文件中所有符合模式的元素都會被選出來,所以可能會有多個。
如下方示例, XPath2 的元素 包括 XPath1的元素(若存在),但不一定僅僅表示XPath1(可能會有多個符合);
XPath3 為表格元素,若該頁面僅存在一個 table,該層級表示法就比較直觀,第1行第3列
XPath1: /html/body/div[1]/div[2]/div[1]/div[2]/div[1]/a
XPath2: //div[2]/div[1]/a
XPath3: //tr[1]/td[3]
若頁面較復雜,顯然取絕對路徑會很長,而且若其中任一層級改動就會導致該XPath失效,/(ㄒoㄒ)/ ; 取相對路徑可以減少 XPath 失效可能性,但可能產生多個元素匹配以致元素取錯,這就需要判斷該XPath是否可用了(下面會介紹使用瀏覽器插件來驗證XPath)。
屬性描述
XPath 語法支持節點描述,節點描述為一個邏輯真假表達式,任何真假判斷表達式都可在節點后方括號里表示,這條件必須在XPath處理這個節點前先被滿足。在某一步驟可有多少個描述並沒有限制。
對於頁面元素, 可用XPath 表示為 html l標簽的屬性值來定位,以百度首頁為例,查看如下幾個 XPath的表示法:
XPath1: //*[@id="su"]
XPath2: //*[@value="百度一下"]
XPath3: //input[@class="bg s_btn"]
XPath4: //*[@id="lg"]/img
XPath5: //a[@class="mnav"]
XPath6: //a[@class="mnav"][2]
XPath1、2、3 實際上表示的均為“百度一下” 元素,只是選取的屬性值的不同; 另,這邊使用了通用符 * 表示匹配任意
XPath4 表示符合[@id="lg"]元素的下層img標簽,即下圖中百度的圖片
XPath5 表示為 class="mnav" (樣式)的標簽,下圖可見多個鏈接都符合該表示法; XPath6 定位了第2個符合該條件的元素,即下圖的 hao123 鏈接
XPath 選取策略
最理想的情況莫過於Id,唯一且開發一般不會做改動(上述例子XPath1)
其次是某Id層級下的元素(較簡單的層級)(上述例子XPath4)
再次為,可確保該頁面下屬性值唯一且一般不做改動的,如 value="百度一下"(上述例子XPath2)
若是表格或者表單,//tr[1]/td[3] 、 //form/button 類似的表示方式也是比較可取的,但須注意頁面標簽的唯一性
XPath 相關插件
Selenium IDE (FireFox 插件)
其中 Target 輸入框,可顯示對應元素的 XPath 表示;可使用 Select 及 find
優點:1. 可自動化錄制回放,顯示直觀,且 易用; 2. 多種可選 (屬性及層級); 3. 唯一性保證
缺點:1. 僅支持FireFox; 2. div[1] 類似 [1] 不顯示,顯示為 div (chrome webdriver 缺失[1]可能會定位不到); 3. 多元素定位不可
Chrome 插件 XPather
優點:1. 使用直觀,易用; 2. 可顯示出所有滿足該XPath表達式的所有元素;
缺點:1. 僅支持Chrome; 2. 需已知XPath; 3. 頁面部分遮蓋
優點:1. 使用直觀,易用; 2. 可顯示出所有滿足該XPath表達式的所有元素; 3. 置於F12工具; 4. 有歷史記錄
缺點:1. 僅支持Chrome; 2. 需已知XPath;