一、介绍
appium定位一个元素,可通过find_element_by_id、find_element_by_class_name、find_element_by_accessibility_id、find_element_by_xpath方式来定位元素。
若元素存在,则返回appium.webdriver.webelement.WebElement对象;
若元素不存,则报错selenium.common.exceptions.NoSuchElementException。
备注:定位元素,必须保证元素的唯一性,否则会导致定位失败或定位错误。
二、通过id定位元素
- find_element_by_id(id_)
id_:定位工具上元素的resource-id属性值
# 通过定位工具获取的resource-id属性值为"com.autonavi.minimap:id/linear_path_container"
element_id = driver.find_element_by_id("com.autonavi.minimap:id/linear_path_container")
三、通过class定位元素
- find_element_by_class_name(name)
name:定位工具上元素的class属性值
# 通过定位工具获取的class属性值为"android.widget.TextView"
element_class = driver.find_element_by_class_name("android.widget.TextView")
四、通过accessibility_id定位元素
- find_element_by_accessibility_id(accessibility_id)
accessibility_id:定位工具上元素的content-desc属性值
# 通过定位工具获取的content-desc属性值为"查路线"
element_desc = driver.find_element_by_accessibility_id("查路线")
五、通过xpath定位元素
- find_element_by_xpath(xpath)
xpath:元素的xpath值
1. 通过xpath定位text属性元素
appium1.5之前的版本可通过find_element_by_name方式来定位text属性元素,但appium1.5之后的版本已不再支持此方式了,若强制使用此方式会报错(selenium.common.exceptions.InvalidSelectorException: Message: Locator Strategy 'name' is not supported for this session)。故只能通过xpath的方式定位
- xpath = "//*[@text='text属性值']"
*表示匹配任意class名称下满足text属性值的元素 - xpath = "//class属性值[@text='text属性值']"
表示匹配特定class名称下满足text属性值的元素
# 通过定位工具获取的text属性值为"查找地点、公交、地铁"
element_xpath_text1 = driver.find_element_by_xpath("//*[@text='查找地点、公交、地铁']")
element_xpath_text2 = driver.find_element_by_xpath("//android.widget.TextView[@text='查找地点、公交、地铁']")
2. 通过xpath定位id属性元素
- xpath = "//*[@resource-id='id属性值']"
*表示匹配任意class名称下满足id属性值的元素 - xpath = "//class属性值[@resource-id='id属性值']"
表示匹配特定class名称下满足id属性值的元素
# 通过定位工具获取的resource-id属性值为"com.autonavi.minimap:id/btn_search"
element_xpath_id1 = driver.find_element_by_xpath("//*[@resource-id='com.autonavi.minimap:id/btn_search']")
element_xpath_id2 = driver.find_element_by_xpath("//android.widget.TextView[@resource-id='com.autonavi.minimap:id/btn_search']")
3. 通过xpath定位class属性元素
- xpath = "//class属性值"
- xpath = "//*[@class='class属性值']"
# 通过定位工具获取的class属性值为"android.widget.TextView"
element_xpath_class1 = driver.find_element_by_xpath("//android.widget.TextView")
element_xpath_class2 = driver.find_element_by_xpath("//*[@class='android.widget.TextView']")
4. 通过xpath定位content-desc属性元素
- xpath = "//*[@content-desc='content-desc属性值']"
*表示匹配任意class名称下满足content-desc属性值的元素 - xpath = "//class属性值[@content-desc='content-desc属性值']"
表示匹配特定class名称下满足content-desc属性值的元素
# 通过定位工具获取的content-desc属性值为"查路线"
element_xpath_desc1 = driver.find_element_by_xpath("//*[@content-desc='查路线']")
element_xpath_desc2 = driver.find_element_by_xpath("//android.widget.LinearLayout[@content-desc='查路线']")
5. 通过xpath进行模糊定位
模糊定位使用contains方法
- xpath = "//*[contains(@属性, '模糊属性值')]"
# resource-id属性值"com.autonavi.minimap:id/btn_search"
contains_id = driver.find_element_by_xpath("//*[contains(@resource-id, 'id/btn_search')]")
# text属性值"查找地点、公交、地铁"
contains_text = driver.find_element_by_xpath("//*[contains(@text, '查找')]")
# class属性值"android.widget.TextView"
contains_class = driver.find_element_by_xpath("//*[contains(@class, 'TextView')]")
# content-desc属性值为"查路线"
contains_desc = driver.find_element_by_xpath("//*[contains(@content-desc, '路线')]")
6. 通过xpath进行组合定位
6.1. class属性与其他属性(resource-id、text、content-desc)组合
- xpath = "//class属性值[@其他属性, '对应的属性值']"
前面几条已写过
6.2. text、resource-id、content-desc、index、class等属性任意组合
- xpath = "//*[@属性1='属性1对应的值'] and @属性2='属性2对应的值']"
- xpath = "//*[contains(@属性1, '属性1对应的模糊值') and @属性2='属性2对应的值']"
- xpath = "//*[contains(@属性1, '属性1对应的模糊值') and contains(@属性2, '属性2对应的模糊值')]"
# xpath进行组合定位
resource-id属性值"com.autonavi.minimap:id/btn_search"
text属性值"查找地点、公交、地铁"
class属性值"android.widget.TextView"
# 具体代码
group_class_text1 = driver.find_element_by_xpath("//android.widget.TextView[@text='查找地点、公交、地铁']")
group_class_text2 = driver.find_element_by_xpath("//*[@class='android.widget.TextView' and @text='查找地点、公交、地铁']")
group_text_index = driver.find_element_by_xpath("//*[@text='查找地点、公交、地铁' and @index='1']")
group_class_text3 = driver.find_element_by_xpath("//*[@class='android.widget.TextView' and contains(@text, '查找')]")
group_class_text4 = driver.find_element_by_xpath("//*[contains(@class, 'TextView') and contains(@text, '查找')]")
7. 通过xpath进行层级定位
7.1. 从上向下层级定位元素
方法:先获取元素的父或祖,再往下层级定位元素(祖定位父,父再定位子)
(1)子或父仅有一个时:
xpath = "//*[@父属性='父属性值']/子class属性值"
xpath = "//*[@祖属性='祖属性值']/父class属性值/子class属性值"
(2)子或父有多个相同的class属性值时添加索引:
**注**:索引号指相同class属性值下对应的第几个值,从1开始取值,而非从0开始取值。
xpath = "//*[@父属性='父属性值']/子class属性值[索引号]"
xpath = "//*[@祖属性='祖属性值']/父class属性值[索引号]/子class属性值[索引号]"
(3)父或祖属性为class定位的另一种方法:
xpath = "//祖class属性值/父class属性值[索引号]/子class属性值[索引号]"
xpath = "//父class属性值/子class属性值[索引号]"
# 通过父ListView定位第二个LinearLayout元素
xpath_down = driver.find_element_by_xpath("//*[@resource-id='android:id/list']/android.widget.LinearLayout[2]")
xpath_down_class = driver.find_element_by_xpath("//android.widget.ListView/android.widget.LinearLayout[2]")
7.2. 从下向上层级定位元素
方法:先获取元素的子孙,再往上层级定位元素(子定位父,父再定位祖)
(1)子定位父
xpath = "//*[@子属性='子属性值']/.."
xpath = "//*[@子属性='子属性值']/parent::*"
xpath = "//*[@子属性='子属性值']/parent::父class属性值"
(2)子定位父再定位祖
xpath = "//*[@子属性='子属性值']/../.."
xpath = "//*[@子属性='子属性值']/parent::*/parent::*"
xpath = "//*[@子属性='子属性值']/parent::父class属性值/parent::父class属性值"
# 子定位父
xpath_up1 = driver.find_element_by_xpath("//*[@text='双卡和移动网络']/..")
xpath_up2 = driver.find_element_by_xpath("//*[@text='双卡和移动网络']/parent::*")
xpath_up3 = driver.find_element_by_xpath("//*[@text='双卡和移动网络']/parent::android.widget.RelativeLayout")
# 子定位父,父定位祖
xpath_up_up = driver.find_element_by_xpath("//*[@text='双卡和移动网络']/../..")
7.3. 兄弟之间定位
方法:先获取元素的父,再通过父获取兄弟元素(子1定位父,父再定位子2)
xpath = "//*[@属性='属性值']/../兄弟class属性值"
# 先定位父,再往下定位兄弟
xpath_brother = driver.find_element_by_xpath("//*[@text='蓝牙']/../android.widget.TextView")