一、xpath高級用法基礎格式
格式
/軸方法::標籤名[標籤屬性]
實例
//div/parent::span[@name=‘interName’]
實例解釋:
定位span標籤,span標籤是div標籤的父級,且span標籤的name屬性值爲:interlNmae
二、基礎格式詳解
2.1層級路徑格式
表達式
描述
/
從根節點選取(絕對路徑)
//
選取匹配的節點
.
選取當前節點
..
選取當前節點的上級節點
|
並且
表達式
描述
/div
從根節點選取div標籤
//div
選取所有div標籤
//div/..
選取div標籤的上級標籤
list/tr
選取所有父級爲list的tr標籤
list//tr
選取list標籤節點內的所有tr標籤
/div/span | /div/input
選取div標籤下的span和div標籤下的input
2.2標籤位置以及標籤屬性
備註:ends-with()方法我在使用時發現無效。
表達式
描述
*
選取任意的節點
@
選取標籤本身的屬性
@*
選取帶有任何屬性的節點
last()
選取當前層級的最後一個標籤
position()
選取當前層級中標籤的具體位置定位
contains(text(),’’)
選取標籤內容包含匹配文本的節點
starts-with()
選取標籤屬性值開始字段匹配
ends-with()
選取標籤屬性值結束字段匹配
attribute
等同於@,屬於xpath方法
表達式
描述
/div/span[2]
選取div標籤下第二個span標籤
/table/*
選取table標籤下所有子節點
/input[@id=‘userName’]
選取所有id屬性值爲:userName的input標籤
/list[@*]
選取所有帶屬性的list標籤
/span[last()-1]
選取當前層級的倒數第二個span標籤
/li/div[position() < 3]
選取li標籤下前兩個div元素
/input[contains(text(),‘密碼’)]
選取節點中內容包含:密碼的input標籤
//input[contains(@id,‘Name’)]
選取標籤中id屬性包含Name的input的標籤
/div[starts-with(@*,‘na’)]
選取標籤中任意屬性值以na開始的div標籤
/div[ends-with(text(),‘名’)]
選取節點中內容以‘名’結尾的div標籤
2.3xpath軸方法
表達式
描述
parent
選取當前節點的父節點。
ancestor
選取當前節點的所有前輩
child
選取當前節點內的所有子標籤
descendant
選取當前節點內的所有後代
following
選取當前html頁面,這個節點結束標籤之後的所有節點
preceding
選取當前html頁面,這個節點結束標籤之前的所有節點
following-sibling
選取當前節點之後的所有同級節點
preceding-sibling
選取當前節點之前的所有同級節點
表達式
描述
/parent::div
選取當前節點的div父標籤。
/ancestor::div
選取當前節點之上的所有div標籤(父、祖父節點)
/td/child::tr
選取td標籤下的所有tr子標籤
/td/descendant::tr
選取td標籤內的所有tr標籤(不限層級)
/table/following:: *
選取當前html頁面,table標籤結束之後的所有標籤(無視層級)
/table/preceding :: *
選取當前html頁面,table標籤之前的所有標籤(無視層級)
/div/following-sibling::div
選取div標籤之後的所有同級div標籤
/div/preceding-sibling::div
選取當前節點之前的所有同級div標籤
2.4常用運算符
表達式
示例
and
/input[@id=‘name’ and @weight=‘10’]
or
/input[@id=‘name’ or @weight=‘10’]
=
/input[@name=‘test’]
!=
/ipnut[@name!=‘test’]
2.5 附錄:一些等價的寫法
建議書寫表達式
等價表達式
/input[@name=‘test’]
/input[attribute::name=‘text’]
/a[5]
/a[position()=5]
div/parent::span
div/..
三、實例演示
常見場景:輸入框定位
有時候經常遇到輸入框表單很多,也沒有唯一標識id等,chrome複製的xpath非常的長,而且容易失效,但是如果根據輸入框前的字段名稱來作爲標識,那定位就比較穩定了。
這裏我來演示的是百度的註冊頁面,這裏輸入框的輸入通過字段名稱來作爲唯一標識,來定位輸入框
xpath = //label[text()=‘用戶名’]/following-sibling::input[last()]
代碼示例:
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.set_page_load_timeout(15)
driver.get("https://passport.baidu.com/v2/?login")
# 點擊註冊
driver.find_element("xpath", "//a[text()='立即註冊']").click()
# 切換頁籤
all_handle = driver.window_handles
driver.switch_to.window(all_handle[1])
# 定位標籤
driver.find_element("xpath", "//label[text()='用戶名']/following-sibling::input[last()]").send_keys("用戶西城")
driver.find_element("xpath", "//label[text()='手機號']/following-sibling::input[last()]").send_keys("18888888888")
driver.find_element("xpath", "//label[text()='密碼']/following-sibling::input[last()]").send_keys("U1sd23456")
四、常見問題和經驗總結
問題:parent定位父級,還是包含父級、伯父級等
答:parent只定位到父級
問題:符合xpath路徑的元素有多個,此時driver如何判斷對哪一個元素進行操作呢
答: find_element方法中,如果符合路徑的元素有多個,默認取第一個元素
contains(text(),’‘要查找的文字’),定位時只能定位當前標籤層級中的文本
Unable to locate element
方法1:加入time.sleep() (ui自動化中操作過快會多導致無法定位到元素)
方法2:加入顯示等待:WebDriverWait、expected_conditions
方法3:可能是由於操作導致層級結構改變,重新排查定位元素路徑
方法4:可能是頁面中包含frame嵌套,加入switch_to.frame
Element is not currently visible and may not be manipulated exception
方法1:下拉框沒有成功選擇數據,此時對於下拉框的定位取消顯式等待
unexpected EOF while parsing
方法1:運行報錯,檢查是否是class中函數格式是否正確