前面已经介绍了环境搭建和入门实例,为了更深入的学习,需要熟练掌握各种元素定位方法,以便于应用到具体的实例场景,本章主要涉及到的内容有;
-
find_element_by_id
-
find_element_by_class_name
- find_element_by_accessibility_id
-
find_element_by_xpath
-
find_element_by_android_uiautomator
-
driver.tap
一、通过id定位元素(find_element_by_id)
对应的字段是resrouce-id,一般会优先用id定位,但id有时候并不唯一,使用前要判断下id是否唯一
# id定位到首页 driver.find_element_by_id("com.taobao.taobao:id/iv_image").click()
二、通过ClassName定位元素(find_element_by_class_name)
对应的字段是class,clsaa属性决定了界面元素的类型,如果要查找某种类型的界面元素,且该类型界面元素在当前界面中只有一个,则可以使用此方法,但是by_class_name使用频率不是很高,因为很容易出现多个元素的class是一样的一。
# class定位到输入框 driver.find_element_by_class_name("android.widget.EditText").click()
三、通过content-desc定位元素(find_element_by_accessibility_id)
对应的字段是content-desc,content-desc属性是用来描述该元素的作用,如果要查询的界面元素的content-desc在当前界面唯一,则可以使用此方法,大部分情况下,该字段为空
# content-desc定位到搜索按钮 driver.find_element_by_accessibility_id('搜索').click()
四、通过xpath定位元素(find_element_by_xpath)
当以上方法都无法定位到具体元素时,可以采用xpath方法定位元素
1、如果元素text是唯一的,可以通过text文本定位
#当页面的text判断出是唯一 driver.find_element_by_xpath("//*[@text='评价']").click()
2、如果元素id是唯一的,也可以id属性定位
# id定位确定 driver.find_element_by_xpath("//*[@resource-id='com.taobao.taobao:id/confirm_text']").click()
3、通过text和id联合定位
# id和text组合定位到评价页 driver.find_element_by_xpth("//*[@resource-id='com.taobao.taobao:id/taodetail_nav_bar_tab_text'][@text='评价']").click()
4、class属性唯一的话,同样可以通过class属性定位,有两种方法
# 第1种方法 driver.find_element_by_xpath("//android.widget.EditText").click() # 第2种方法 driver.find_element_by_xpath("//*[@class='android.widget.EditText']").click()
5、通过content-desc属性定位,contains是模糊匹配的定位方法,对于一个元素的id或者text不是固定的,但有一部分是固定的,这种就可以模糊匹配。
# 第1种:匹配text,模糊定位到宝贝评价 driver.find_element_by_xpath("//*[contains(@text,'宝贝评价')]").click() # 第2种:匹配content-desc,模糊定位到返回 driver.find_element_by_xpath("//*[contains(@content-desc,'返回')]").click() # 第3种:匹配class,模糊定位到输入框 driver.find_element_by_xpath("//*[contains(@class, 'android.widget.EditText')]").click() # 第4种:匹配到id,模糊定位到输入框 driver.find_element_by_xpath("//*[contains(@resource-id, 'com.taobao.taobao:id/searchEdit')]").click()
6、组合定位
如果一个元素有2个属性,通过xpath也可以同时匹配2个属性,text, resource-id,class ,index,content-desc这些属性都能任意组合定位
# id和class属性 定位搜索框 id_class = '//android.widget.EditText[@resource-id="com.taobao.taobao:id/home_searchedit"]' driver.find_element_by_xpath(id_class).click() time.sleep(3) driver.back() # text和index属性 定位登录/注册 desc_class = '//*[@text="注册/登录" and @index="1"]' driver.find_element_by_xpath(desc_class).click() time.sleep(3) # class和text属性 定位输入手机号 class_text = '//android.widget.EditText[@text="请输入手机号码"]' driver.find_element_by_xpath(class_text).send_keys("512200893") time.sleep(3) # class和desc 定位帮助 id_desc = '//*[contains(@resource-id, "aliuser_menu_item_help") and @content-desc="帮助"]' driver.find_element_by_xpath(id_desc).click()
7、层级定位
如果一个元素,它除了class属性(class属性肯定会有),其它属性啥都没有,这种情况用上面方法就不适用了,这个时候可以找他父元素,通过父亲定位儿子
#如果一个父元素下,有多个相同class的儿子时候,可以通过xpath的索引去取对应第几个,xpath是从1开始数的 loc_class='//*[@resource-id="com.taobao.taobao:id/libsf_srp_header_list_recycler"]/android.widget.RelativeLayout[2]' driver.find_element_by_xpath(loc_class).click()
相反的,可以通过儿子定位父亲
# 通过子元素定位父元素 # 方法一: .. sun_fa1 = '//*[@resource-id="com.taobao.taobao:id/tv_scan_text"]/..' c = driver.find_element_by_xpath(sun_fa1).tag_name print(c) # 方法二 parent::* sun_fa2 = '//*[@resource-id="com.taobao.taobao:id/tv_scan_text"]/parent::*' d = driver.find_element_by_xpath(sun_fa1).tag_name print(d) # 方法三 parent::android.widget.LinearLayout sun_fa3 = '//*[@resource-id="com.taobao.taobao:id/tv_scan_text"]/parent::android.widget.LinearLayout' e = driver.find_element_by_xpath(sun_fa1).tag_name print(e)
通过子元素,先找到父元素,再找父元素下的子元素,同样可以进行兄弟元素定位
# 兄弟元素 xiongdi = '//*[@resource-id="com.taobao.taobao:id/bar_search"]/../android.widget.RelativeLayout' x = driver.find_element_by_xpath(xiongdi).tag_name print(x)
通过层级关系,一层一层的往下找,同样可以通过爷爷元素,定位到孙子元素
#爷爷元素FrameLayout---第一个FrameLayout儿子---孙子TextView x = '//android.widget.FrameLayout/android.widget.LinearLayout[1]/android.widget.TextView' t = driver.find_elements_by_xpath(x) print(len(t)) # 打印文本信息 print(t[0].text
五、通过AndroidUiAutomator定位元素(find_element_by_android_uiautomator)
AndroidUIAutomator是一个强有力的元素定位方式,它是通过Android UIAutomator类库去找元素,可以选择id、name、className作为传入的字符串
1、通过id定位
# 通过id定位到商品 ui_id='new UiSelector().resourceId("com.taobao.taobao:id/goodsimage")' driver.find_element_by_android_uiautomator(ui_id).click()
2、通过text定位
# 通过text定位加入购物车按钮 ui_text='new UiSelector().text("加入购物车")' driver.find_element_by_android_uiautomator(ui_text).click()
3、通过class定位
#classname 复数定位,通过class定位某个商品 ui_class='new UiSelector().className("android.widget.RelativeLayout")' driver.find_element_by_android_uiautomator(ui_class[1]).click()
4、组合定位,一般组合用id,class,text这三个属性
# 第1种:id和text组合定位到加入购物车 id_text='resourceId("com.taobao.taobao:id/detail_main_sys_button").text("加入购物车")' driver.find_element_by_android_uiautomator(id_text).click() # 第2种:class和text组合定位到加入购物车 class_text = 'className("android.widget.TextView").text("加入购物车")' driver.find_element_by_android_uiautomator(class_text).click()
5、description,也是用contenet-des属性定位
# 通过content-desc定位到返回 ui_content_desc='new UiSelector().description("返回")' driver.find_element_by_android_uiautomator(ui_content_desc)
6、父子定位childSelector,有时候不能直接定位某个元素,但是它的父元素很好定位,这时候就先定位父元素,通过父元素找儿子
#父子关系childSelector son = 'resourceId("com.baidu.yuedu:id/rl_tabs").childSelector(text("小说"))' driver.find_element_by_android_uiautomator(son).click()
6、兄弟定位fromParent,有时候父元素不好定位,但是跟他相邻的兄弟元素很好定位,这时候就可以通过兄弟元素,找到同一父级元素下的子元素
#兄弟关系fromParent brother = 'resourceId("com.baidu.yuedu:id/lefttitle").fromParent(text("图书"))' driver.find_element_by_android_uiautomator(brother).click()
六、通过tap定位元素(driver.tap)
tap(self, positions, duration=None):模拟手指点击(最多五个手指),可设置按住时间长度(毫秒)
- positions - list类型,里面对象是元组,最多五个。如:[(100, 20), (100, 60)] - duration - 持续时间,单位毫秒,如:500
# tap坐标方式定位到运动 driver.tap([(720,72),(1080,216)],500)
以上定位元素,其中层级、父级、兄弟定位是尚未用到的,文中的用法是摘抄了其他博客,后续有遇到合适的场景时会回来贴图。