被測試網頁的HMTL代碼html
<html> <body> <div id="div1"> <input name="div1input"></input> <a href="http://www.sogou.com">搜狗搜索</a> <img alt="div1-img1" src="http://www.sogou.com/images/logo/new/sogou.png" href="http://www.sogou.com">搜狗圖片</img> <input type="button" value="查詢"></> </div> <br> <div name="div2"> <input name="div2input"></input> <a href="http://www.baidu.com">百度搜索</a> <img alt="div2-img2" src="http://www.baidu.com/img/bdlogo.png" href="http://www.baidu.com">百度圖片</img> </div> </body> </html>
絕對路徑定位方式:web
在被測試網頁中,查找第一個 div 標籤中的按鈕。app
XPath的表達式: /html/body/div/input[@value="查詢"]函數
Java的定位語句: WebElement button= driver.findElement(By.xpath("/html/body/div/input[@value='查詢']"));測試
相對路徑定位方式:spa
在被測試網頁中,查找第一個 div 標籤中的按鈕。
XPath的表達式:
// input[@value="查詢"]
Java的定位語句:
WebElement button= driver.findElement(By.xpath("//input[@value='查詢']"));code
XPath 使用索引號定位:htm
被測試網頁的HMTL代碼blog
使用索引號定位方式: 在被測試網頁中,查找第二個 div 標籤中的「查詢」按鈕。索引
XPath的表達式: //input[2]
Java的定位語句: WebElement button= driver.findElement(By.xpath("//input[2]"));
XPath 使用頁面元素的屬性值定位:
使用頁面屬性值方式:
咱們嘗試定位被測試網頁中的第一個圖片元素。
XPath 的表達式
//img[@alt='div1-img1']
Java的定位語句:
WebElement img= driver.findElement(By.xpath("//img[@alt='div1-img1']"));
XPath 使用頁面元素的屬性值定位:
預期定位的頁面元素 |
定位表達式示例 |
使用的屬性值 |
定位頁面的第一個圖片 |
//img[@href='http://www.sogou.com'] |
使用img標籤的href屬性值 |
定位第二個div中第一個Input輸入框 |
//div[@name='div2']/input[@name='div2input'] |
使用div標籤的name屬性值 使用 input標籤的name 屬性值 |
定位第一個div中的第一個連接 |
//div[@id='div1']/a[@href='http://www.sogou.com'] |
使用的div標籤的id 屬性值 使用了a標籤的href屬性值 |
定位頁面的查詢按鈕 |
//input[@type='button'] |
使用了type屬性值 |
XPath 使用模糊頁面屬性值定位:
XPath函數 |
定位表達式示例 |
表達式解釋 |
Starts-with() |
//img[starts-with(@alt,'div1')] |
查找圖片alt屬性開始位置包含’div1’關鍵字的頁面元素 |
Contains() |
//img[contains(@alt,'g1')] |
查找圖片alt屬性包含’g1’關鍵字的頁面元素 |
使用 XPath 的軸(axis)進行元素定位:
軸:
XPath軸(XPath Axes)可定義某個相對於當前節點的節點集:
一、child 選取當前節點的全部子元素
二、parent 選取當前節點的父節點
三、descendant 選取當前節點的全部後代元素(子、孫等)
四、ancestor 選取當前節點的全部先輩(父、祖父等)
五、descendant-or-self 選取當前節點的全部後代元素(子、孫等)以及當前節點自己
六、ancestor-or-self 選取當前節點的全部先輩(父、祖父等)以及當前節點自己
七、preceding-sibling 選取當前節點的開始標籤以前的全部同級節點
八、following-sibling 選取當前節點的結束標籤以後的全部同級節點
九、preceding 選取文檔中當前節點的開始標籤以前的全部節點
十、following 選取文檔中當前節點的結束標籤以後的全部節點
十一、self 選取當前節點
十二、attribute 選取當前節點的全部屬性
1三、namespace 選取當前節點的全部命名空間節點
![]() |
|||
XPath軸關鍵字 |
軸的含義說明 |
定位表達式示例 |
表達式解釋 |
ancestor |
選擇當前節點上層的全部節點 |
//img[@alt='div2-img2']/ancestor::div |
查找到alt屬性值爲div2-img的圖片,並基於圖片位置找到他上級的div頁面元素 |
descendant |
選擇當前節點下層的全部節點 注:不能超出當前節點的結束標籤 |
//div[@name='div2']/descendant::img |
查找到name屬性值的div頁面元素,並基於div的位置找到他下級全部節點中的img頁面元素 |
following |
選取當前節點的結束標籤以後的全部節點 注:仔細體會與descendant的區別 |
//div[@id='div1']/following::img |
超找到id 屬性值爲div1的div頁面元素,並基於div的位置找到它後面(結束標籤以後)節點中的img頁面元素 |
following-sibling |
選取當前節點的結束標籤以後的全部平級節點 ,自上而下,離當前結點最近的爲索引1,越往下數字越大。 |
//a[@href='http://www.sogou.com']/follo wing-sibling::input |
查找到連接地址爲http://www.sogou.com的連接頁面元素,並基於連接的位置找到它後續節點中input頁面元素 |
preceding |
選擇當前節點開始標籤以前的全部節點 |
//img[@alt='div2-img2']/preceding::div |
查找到alt屬性值爲div2-img2的圖片頁面元素,並基於圖片的位置找到它前面節點中的div頁面元素 |
preceding-sibling |
選擇當前節點開始標籤以前的全部同級節點,自下而上,離當前結點最近的爲索引1,越往上數字越大。 |
//img[@alt='div2-img2']/preceding-sibling ::a[1] |
查找到alt屬性值爲div2-img2的圖片頁面元素,並基於圖片的位置找到它前面同級節點中的第二個連接頁面元素 |
XPath 使用頁面元素的文本定位:
例1:
使用text()函數能夠定位到包含某些關鍵字的頁面元素
XPath的表達式:
1) //a[text()='百度搜索']
2) //a[contains(text(),'百度')]
3) //a[contains(text(),'百度')]/preceding::div
Java 的定位語句:
WebElement a=driver.findElement(By.xpath("//a[text()='百度搜索']"));
WebElement a=driver.findElement(By.xpath("//a[contains(text(),'百度')]"));
WebElementdiv=driver.findElement(By.xpath("//a[contains(text(),'百 度')]/preceding::div"));
例2:實際項目
目的:經過角色名稱,來點擊'編輯'這個圖片超連接。
1 name 表示角色名稱 2 3 lineXpath = u"//div[@id='body2']/descendant::a[text()='%s']" % name 4 editXpath = u"%s/ancestor::tr/descendant::img[@title='編 輯']" % lineXpath 5 webApi.clickBy(driver, by.xpath_(editXpath), 2, 0)
例3:實際項目
目的:經過輸入框定位框前面的標題和框後面的提示信息。使用ancestor而不用parent,由於當前元素的父元素可能不是td(嵌套div之類的),後面的preceding-sibling必定要加,不加會定位多個td,包括頂層的td。
1 def getTipInfo2(driver, idList):
2 u'返回以輸入框標題爲key,以提示信息爲value的字典'
3 msgList = [] 4 for editId in idList: 5 titleXpath = u"//*[@id='%s']/ancestor::td/preceding-sibling::td[1]" % editId 6 title = webApi.getTextBy(driver, by.xpath_(titleXpath), 2) 7 tipInfo = webApi.getTextBy(driver, by.id_(editId + u'Tip'), 2) 8 tempTuple = title, tipInfo 9 msgList.append(tempTuple) 10 for k, v in dict(msgList).iteritems(): 11 if (u'OK' not in v) and (len(v.strip())>0): 12 print u"操做項'%s'失敗,提示信息:'%s'" % (k, v) 13 return dict(msgList)
結果:
操做項'選擇角色*:'失敗,提示信息:'管理員角色必填!' 操做項'管理員帳號*:'失敗,提示信息:'管理員帳號必填,長度爲1-64個字符!' 操做項'靜態密碼*:'失敗,提示信息:'密碼必填,長度4-32個字符!' 操做項'確認靜態密碼*:'失敗,提示信息:'確認密碼必填,長度4-32個字符!'
td[1]表示id=adminid這個元素上面倒數第一個td,即便用preceding-sibling時,是下往上看的,離adminid最近的爲td[1];而使用following-sibling時,是上往下看的,注意順序,能夠看下面這個例子。
例4:打印經常使用控件標題及內容
HTML和頁面以下:
代碼:
1 def printInputInfo(driver, key_id, value, inputType=u'edit'): 2 u'打印經常使用控件標題及內容' 3 u''' 4 args: 5 key_id: 頁面輸入元素的ID 6 value: 輸入的值 7 inputType:輸入元素的類型 8 ''' 9 #標題xpath 10 xp = u"//*[@id='%s']/ancestor::td/preceding-sibling::td[1]" % key_id 11 #取標題 12 title = webApi.getTextBy(driver, by.xpath_(xp), 2) 13 14 if inputType == u'edit': 15 t = u'編輯框' 16 elif inputType == u'select': 17 t = u'下拉選擇框' 18 elif inputType == u'tree': 19 t = u'樹狀選擇器' 20 elif inputType == u'radio': 21 t = u'單選按鈕' 22 elif inputType == u'checkbox': 23 t = u'複選框' 24 print u"%s---%s %s" % (t, title.strip(), value)
當程序執行到輸入令牌號,會打印控件類型、標題、輸入值,如 "編輯框---令牌號: 2600321700067"。
此處使用preceding-sibling::td[1],若用td[3],則輸出 "編輯框---組織機構: 2600321700067"。