元素定位大緻可以分兩類,絕對路徑定位和相對路徑定位,前者即使走投無路也不推薦使用,因為絕對路徑經常會發生變化,後者比較常用的。但是相對路徑定位方式有很多,需要選一種最有利于腳本相容性的方式。
1.絕對路徑定位
逐層輸出元素的位置,如:
//*[@id="app"]/div/div[2]/section/div/div/div[1]/div/div/button/span
絕對路徑可直接從浏覽器調試視窗擷取,但此方式最不可取的,代碼結構稍做調整就會不适用,是以即使找不到定位的方式,也不建議使用。
2.相對路徑定位
相對路徑定位,需要找到确定元素唯一性的特征,定位元素位置。在此分享10種方法,可依次嘗試定位。
2.1 id屬性定位
最理想的方式,就是使用id屬性定位,id一般在目前界面具有唯一性。

圖 2-1
圖2-1中代碼id在目前界面唯一,是以我們最優先選擇的定位方式是使用id,隻需尋找id=“table-1”的元素即可,是以xpath代碼可寫為:
//div[@id="tab-1"]
//*[@id="tab-1"]
//表示相對路徑,@後跟屬性,*表示任何比對任何節點
2.2 name屬性定位
當name屬性唯一時,也可用來定位。
圖 2-2
如圖2-2中name也具有唯一性,也可以通過name來定位元素的位置:
//input[@name="wd"]
2.3 class屬性定位
适用于class屬性在目前界面具有唯一性的場景。
圖 2-3
class屬性是比較常用的定位元素方式,圖2-3中class具有唯一性,xpath定位如下:
//span[@class="el-pagination__total"]
2.4 标簽名定位
有時元素自身标簽也可實作定位,常見如button、input、textarea等。
圖 2-4
如圖2-4目前界面隻有一個标簽textarea,此時元素可以通過标簽名定位。
//div/textarea
2.5 其他屬性定位
當以上屬性都無法精準定位時,可以考慮placeholder、type、for屬性定位,但方式不一定最優。
圖 2-5
如圖2-5,定位某個标簽的位置,for屬性具體唯一性,但是class不唯一,此時就可以用for屬性定位元素。
//label[@for="name"]
圖 2-6
如圖2-6定位上傳檔案的位置,type可以精準定位到元素,路徑可以寫成:
//input[@type="file"]
圖2-7
placeholder也可以定位,但是不一定最優,若資訊稍有變化就不适用,圖2-7可使用placeholder定位。
//input[@placeholder="如1.0.1"]
此外還有href、title、value等不常用的屬性,此處就不一一詳細說明了,總之隻要具有唯一性的屬性都可以用來定位元素,但是需要衡量是否是最優方式。但是注意有些屬性值是動态生成的,此類屬性不可用于定位。
2.6 使用邏輯運算定位
當單一屬性無法滿足精準定位的需求時,xpath支援邏輯運算支援與(and)、或(or),這個功能還是比較強大的,最常用的是and,即多個屬性确定結合定位元素。
圖 2-8
如登陸界面有好幾處入口,單一屬性都無法精準定位,此時可以herf和class屬性結合,實作定位需求,此功能在腳本中比較常用。
//*[@href="#/login" and @class="router-link-active"]
2.7 通過上級節點定位
當現實沒那麼理想,元素找不到任何可精準定位的屬性時,可以先定位父級的位置,再進行元素定位。
圖 2-9
圖2-9中,父級元素class屬性唯一,是以先定位到父級,再實作自身定位。圖中父級有3個class類,可選取一種用于定位,也可使用多個class類同時定位。
//div[@class="product-name"]/input
//div[@class="productCopy product-name"]/input
或者通過先定位祖輩(更上層的元素),實作元素定位。
圖 2-10
圖2-10是定位的一個送出按鍵位置,元素以及父級屬性都很大衆,此時可以尋找更上級的元素屬性,先定位祖輩位置,再結合元素自身class,唯一确認元素位置。
//div[@class="el-dialog__wrapper delete-dialog"]//button[@class="el-button el-button--primary"]
2.8 通過子節點定位
既然可以通過上層節點定位到子節點,那麼也可以通過子節點實作父節點定位,parent就是比較常用的方式。
圖 2-11
圖2-11中,子節點class屬性目前界面唯一,是以可以先定位到i節點,再找尋它的父節點 。此時有兩種方法可以選擇,“parent::節點名稱”或直接…到上一層級節點,具體表達如下:
//i[@class="icon-plus el-icon"]/parent::span
//i[@class="icon-plus el-icon"]/..
2.9 通過相鄰目錄定位
當無法通過層級關系定位元素時,觀察元素的兄弟姐妹們(相鄰層級的元素)或者家族長輩(上級的相鄰層級元素)的特征,實作元素定位。
圖 2-12
圖2-12相鄰元素很相似,此時可以通過标簽下标定位,當然方式也不一定最優,與其他代碼不同,下标從1開始,如定位第一個元素“賬号資訊”位置:
//ul/li[1]
另一種場景是先找尋上層元素的相鄰元素,結合自身元素屬性,實作定位。
圖2-13
圖2-13中,元素自身和相鄰元素,甚至上級元素都沒有無法精準定位,但是再上層label節點可以精準定位,此時通過與label節點結合,再結合自身input,就可以唯一找到元素位置。
//label[@for="name"]/..//input
…表示上一層級節點
2.10 contain/text方法定位
若是以上方法都不能滿足你的需求,有一個非常強大的功能就可以使用,模糊比對關鍵字。有多種模糊比對方式,如:比對開頭,中間、結尾字段等,使用比較多的是contains(包含),很多場景可以通過模糊比對定位。
圖2-14
圖2-14中元素class屬性,以及上級button屬性都無法精準定位,此時可以通過比對文本進行定位。
//span[contains(text(),'綁定裝置')]
3.總結
元素定位思路與形容某個人很相似:
- 元素單一屬性定位:介紹個人特點,如:他有羽毛扇。
- 元素多屬性組合:單個屬性不唯一,多個屬性組合可唯一确定,如:他謀略超群,且生性多疑。
- 通過上級節點定位:長輩有獨特特征,或者與長輩組合可以确定唯一性,如:他是中山靖王之後,漢景帝玄孫。
- 通過子節點定位:子孫中有特殊人物,如:生子當如孫仲謀
- 通過相鄰元素定位:找尋家族有特征人物,如:他是劉備的結義兄弟,且有文化。
- 模糊比對:比對元素的文本内容,如:他的名字裡有個“龍”字。
- 當以上都無法滿足定位條件時,給親的建議是,找親愛的開發同學,給所需要定位的元素補充上id。
原文作者:zhangyj
點選檢視原文