原文鏈接
XPath高級定位技巧
XPath 簡介
XPath 的英文全稱為:XML Path Language,意旨對 XML 中的元素進行路徑定位的一種語言,它可適用 XML 標記語言,Html 標記語言,app Dom 結構,XPath 是自動化工具的定位基礎,可適用于 Selenium 工具,Appium 工具,Appcrawler 工具,由于前面章節已經對 XPath 進行說明,本篇只做舉例說明,
XPath 基本語法
下面是 XPath 的常用方法:

XPath 模糊定位技巧
contains( )方法是模糊匹配的定位方法,對于一個元素的屬性不固定,就可以模糊匹配,如://[contains(@content-desc, '幫助')],示例代碼:
PYTHON 版本
driver.find_element(By.XPATH,
'//*[contains(@text, "注冊")]')
driver.find_element(By.XPATH,
'//*[contains(@content-desc, "搜索")]')
driver.find_element(By.XPATH,
'//*[contains(@resource-id, "login_phone")]')
JAVA 版本
driver.findElement(By.xpath(
"//*[contains(@text, \"注冊\")]"));
driver.findElement(By.xpath(
"//*[contains(@content-desc, \"搜索\")]"));
driver.findElement(By.xpath(
"//*[contains(@resource-id, \"login_phone\")]"));
XPath 組合定位技巧
通過 XPath 可以同時匹配 2 個甚至多個屬性來完成元素定位,這里常用的屬性有 text、resource-id、class、index、content-desc 等,這些屬性任意組合完成定位,示例代碼:
PYTHON 版本
driver.find_element(
By.XPATH,'//*[@text="我的" and @resource-id="tab_name"]'
).click()
driver.find_element(
By.XPATH,'//*[@text="注冊/登錄" and @index="1"]'
).click()
JAVA 版本
driver.findElement(By.xpath(
"//*[@text=\"我的\" and @resource-id=\"tab_name\"]")).click();
driver.findElement(By.xpath(
"//*[@text=\"注冊/登錄\" and @index=\"1\"]")).click();
XPath 層級定位
通常定位元素的時候可能會涉及到通過子元素去定位父元素,或者父元素定位子元素,或者定位兄弟元素,xpath 支持父子關系,兄弟關系元素的查找,示例代碼如下:
PYTHON 版本
# 通過子元素定位父元素
# 方法一:..
driver.find_element_by_xpath(
'//*[@text="手機號"]/..').tag_name
# 方法二 parent::*
driver.find_element_by_xpath(
'[@text="手機號"]/parent::*').tag_name
#通過元素定位兄弟元素
driver.find_element_by_xpath(
'//*[@text="手機號"]/../li'
).tag_name
JAVA 版本
// 通過子元素定位父元素
// 方法一:..
driver.findElement(By.xpath(
"//*[@text=\"手機號\"]/..")).getTagName();
// 方法二 parent::*
driver.findElement(By.xpath(
"[@text=\"手機號\"]/parent::*")).getTagName();
// 通過元素定位兄弟元素
driver.findElement(By.xpath(
"//*[@text=\"手機號\"]/../li"
)).getTagName();
案例
場景一:
應用:雪球 apk
可以使用 uiautomatorviewer 工具進行 dom 分析,然后對分析到的元素進行 XPath 定位,比如下面的搜索框,可以使用元素的多種屬性進行定位,常用的有 text,resource-id,class,content-desc 等屬性,

推薦使用 resource-id 進行定位,通常情況下,它是頁面唯一的屬性,其 XPath 如下:
PYTHON 版本
driver.find_element(
By.XPATh, '//*[contains(@resource-id, "tv_search")]')
# 或者也可寫成下面這樣
driver.find_element(By.ID, 'tv_search')
JAVA 版本
driver.findElement(By.xpath("//*[contains(@resource-id,
\"tv_search\")]"));
// 或者也可寫成下面這樣
driver.findElement(By.id("tv_search"));
場景二:
如下圖,獲取 “BABA” 所對應的股票價格 “187.11”,可以使用 XPath 父子關系來進行元素定

代碼如下:
PYTHON 版本
curr_price = self.driver.find_element(
MobileBy.XPATH,"//*[@text='BABA']/../../..\
//*[@resource-id='com.xueqiu.android:id/current_price']")
JAVA 版本
MobileElement curr_price = driver.findElement(
By.xpath("//*[@text=\"BABA\"]/../../..//\
*[@resource-id='com.xueqiu.android:id/current_price']"));
Android UiAutomator定位技巧
UiAutomator 是 Android SDK 自帶的一個測驗框架,這個測驗框架提供了一系列的 API,可以與 Android APP 進行互動,例如打開選單,點擊,滑動等,當 Appium 的 Caps 引數 uiautomationName 設定為 UiAutomator2 時,就能夠實作與手機端的 UiAutomator 進行通信并且使用 UiAutomator 執行測驗代碼,如果不進行設定,默認也是使用 UiAutomator2 作業引擎,UiAutomator1 是較老的作業引擎,如果想測驗較老版本的 Android 系統(低于 Android4.4 版本)需要設定 uiautomationName="UiAutomator1",
由于 Android UiAutomator 是 Android SDK 中自帶的作業引擎,使用這種定位方式,速度上要比 Xpath 定位方式快很多,但由于寫法比較特殊,除錯起來要相對麻煩,如果定位陳述句撰寫不當,腳本編輯器也不會給出任何提示資訊,只能在運行的時候校驗對錯,
下面就單獨介紹基于 uiautomator 定位元素的方法,基本語法如下:
- Python 版本
driver.find_element_by_android_uiautomator()
- Java 版本
driver.findElement(MobileBy.AndroidUIAutomator());
常用的方法有:
UiSelector() # 實作元素定位
UiScrollable() # 實作滾動查找元素
通過 TEXT 文本定位
UiSelector( ) 與 XPath 類似,可以通過元素的 text 屬性來定位元素,語法格式如下:
new UiSelector().text("text文本")
同樣也能用模糊查詢的用法去定位元素
例如: new UiSelector().textContains("手機") 示例代碼:
- Python 版本
driver.find_element_by_android_uiautomator(
'new UiSelector().textContains("手機")').click()
- Java 版本
driver.findElementByAndroidUIAutomator(\
"new UiSelector().textContains(\"手機\")").click();
通過 RESOURCEID 定位
uiautomator 同樣也能進行 id 定位,格式為 new UiSelector().resourceId("resource-id屬性"),示例代碼:
- Python 版本
driver.find_element_by_android_uiautomator(
'new UiSelector().resourceId("rl_login_phone")').click()
- Java 版本
driver.findElementByAndroidUIAutomator("new UiSelector().\
resourceId(\"rl_login_phone\")").click();
通過 CLASSNAME 定位
頁面上的 class 屬性一般不唯一,此時可以根據下標進行定位,格式為 new UiSelector().className("className"),一般會使用find_elements完成定位,示例代碼:
- Python 版本
driver.find_elements_by_android_uiautomator(
'new UiSelector().\
className("android.widget.TextView")')[5].click()
- Java 版本
driver.findElementsByAndroidUIAutomator("new UiSelector().\
className(\"android.widget.TextView\")")[5].click();
通過 DESCRIPTION 定位
同樣的,也支持 contenet-desc 定位方式,格式為:new UiSelector().description("contenet-des屬性"),示例代碼:
- Python 版本
driver.find_element_by_android_uiautomator(
'new UiSelector().description("搜索")').click()
- Java 版本
driver.findElementByAndroidUIAutomator("new \
UiSelector().description(\"搜索\")").click();
組合定位方式
Uiautomator 也支持組合元素查找功能,示例代碼:
- Python 版本
driver.find_element_by_android_uiautomator(
'new UiSelector().resourceId(\
"com.xueqiu.android:id/tv_login_phone").text("手機號")').click()
- Java 版本
driver.findElementByAndroidUIAutomator("new UiSelector().resourceId(\
\"com.xueqiu.android:id/tv_login_phone\").text(\"手機號\")").click();
滾動查找元素
Uiautomator 使用 UiScrollable() 實作了滾動查找元素的功能,可以指定滑動到某個元素,示例代碼:
- Python 版本
driver.find_element_by_android_uiautomator(
'new UiScrollable(new UiSelector().scrollable(true)\
.instance(0)).scrollIntoView(new UiSelector()\
.text("我的").instance(0));').click()
- Java 版本
driver.findElementByAndroidUIAutomator(\
"new UiScrollable(new UiSelector().scrollable(true)\
.instance(0)).scrollIntoView(new UiSelector().\
text(\"我的\").instance(0));").click();
上面的代碼,在當前的頁面滾動的查找 text 文本是“我的”這個元素,找到之后執行點擊操作,
css selector元素定位
Appium Server 從 1.19.0 這個版本開始,元素定位增加了 css selector 的支持,appium-uiautomator2-driver 會將 css selector 定位器轉化成 android uiautomator 定位方式,
注意:appium inspector 暫時沒有添加這種定位方式,
由于 UiSelector() 的運算式是 Java 的語法格式,撰寫定位元素的運算式很復雜,代碼撰寫工具(比如 Pycharm,VSCode,IntelliJ IDEA等)也不會有任何提示錯誤資訊,只能是運行時才能發現運算式的錯誤,官方提供了 css selector 的語法,會自動轉成 android uiautomator 的語法結構,這種原生的定位元素的方式,定位速度要更快一些,
詳情參考官方:https://github.com/appium/appium-uiautomator2-driver/pull/410
原始碼地址:https://github.com/appium/appium-uiautomator2-driver/blob/master/lib/css-converter.js
id 定位
可以使用 css selector 語法定位,如下代碼,#igk 表示 css selector 定位符
- Python 版本
driver.find_element_by_css_selector('#igk')
對應 ID 定位器代碼如下:
driver.find_element_by_id('android:id/igk')
- Java 版本
driver.findElementByCssSelector("#igk").click();
對應 ID 定位器代碼如下:
driver.findElementById("android:id/igk").click();
class name 定位
如下代碼,表示 css selector 定位符為 .android.widget.ImageView 的元素
- Python 版本
driver.find_element_by_css_selector('.android.widget.ImageView')
對應 class name 定位器代碼如下:
driver.find_element_by_class_name("android.widget.ImageView")
- Java 版本
driver.findElementByCssSelector(".android.widget.ImageView");
對應 class name 定位器代碼如下:
driver.findElementByClassName("android.widget.ImageView");
text 定位
如下代碼,表示 css selector 定位符為 *[text='作業臺']" 的元素:
- Python 版本
driver.find_element_by_css_selector("*[text='作業臺']")
對應 xpath 定位器代碼如下:
driver.find_element_by_xpath("//*[@text='作業臺']")
- Java 版本
driver.findElementByCssSelector("*[text=\"作業臺\"]");
對應 xpath 定位器代碼如下:
driver.findElementByXPath("//*[@text=\"作業臺\"]");
description 定位
如下代碼,表示 css selector 定位符為 *[description="ContentDescription"] 的元素:
- Python 版本
driver.find_element_by_css_selector('*[description="ContentDescription"]')
對應 accessibility id 定位器代碼如下:
driver.find_element_by_accessibility_id("ContentDescription")
- Java 版本
driver.findElementByCssSelector("*[description=\"ContentDescription\"]");
對應 accessibility id 定位器代碼如下:
driver.findElementByAccessibilityId("ContentDescription");
喜歡軟體測驗的小伙伴們,如果我的博客對你有幫助、如果你喜歡我的博客內容,請 “點贊” “評論” “收藏” 一鍵三連哦,
更多技術文章
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/493111.html
標籤:其他
