Appium+Python-元素定位(常用定位)

  前面已经介绍了环境搭建和入门实例,为了更深入的学习,需要熟练掌握各种元素定位方法,以便于应用到具体的实例场景,本章主要涉及到的内容有;

  • 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是否唯一,如图1
# id定位到首页
driver.find_element_by_id("com.taobao.taobao:id/iv_image").click()  

(图1:id定位到首页)

二、通过ClassName定位元素(find_element_by_class_name)

   对应的字段是class,clsaa属性决定了界面元素的类型,如果要查找某种类型的界面元素,且该类型界面元素在当前界面中只有一个,则可以使用此方法,但是by_class_name使用频率不是很高,因为很容易出现多个元素的class是一样的一。如图2

# class定位到输入框
driver.find_element_by_class_name("android.widget.EditText").click() 

(图2:class定位到输入框)

三、通过content-desc定位元素(find_element_by_accessibility_id)

  对应的字段是content-desc,content-desc属性是用来描述该元素的作用,如果要查询的界面元素的content-desc在当前界面唯一,则可以使用此方法,大部分情况下,该字段为空,如图3

# content-desc定位到搜索按钮
driver.find_element_by_accessibility_id('搜索').click()  

(图3:content-desc定位到搜索按钮)

四、通过xpath定位元素(find_element_by_xpath)

  当以上方法都无法定位到具体元素时,可以采用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()# text和index属性  定位登录/注册
desc_class = '//*[@text="注册/登录" and @index="1"]'
driver.find_element_by_xpath(desc_class).click()# class和text属性  定位输入手机号
class_text = '//android.widget.EditText[@text="请输入手机号码"]'
driver.find_element_by_xpath(class_text).send_keys("512200893")# class和desc  定位帮助
id_desc = '//*[contains(@resource-id, "aliuser_menu_item_help") and @content-desc="帮助"]'
driver.find_element_by_xpath(id_desc).click()

7、层级定位

1)如果一个元素,它除了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()

2)相反的,也可以通过儿子定位父亲

# 通过子元素定位父元素
# 方法一: ..
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)

3)通过子元素,先找到父元素,再找父元素下的子元素,同样可以进行兄弟元素定位,如图4、图5

# 用法一:兄弟元素//android.widget.Button[@text='一键操作'],通过兄弟元素定位自己(筛选功能)android.widget.Button
driver.find_element_by_xpath("//android.widget.Button[@text='一键操作']/../android.widget.Button").click()

 

 

(图4:兄弟元素定位,因为淘宝没有合适的例子,截图的应用是企业微信的应用)

# 用法二:根据兄弟元素定位到自己,再往下找
 driver.find_element_by_xpath("//android.view.View[contains(@text,'地址')]/../android.view.View/android.widget.Image").click()

(图5:用法二的兄弟元素定位)

4)通过层级关系,一层一层的往下找,同样可以通过爷爷元素,定位到孙子元素,如图6

#爷爷元素id:container---第二个android.view.View儿子---第一个孙子android.view.View
driver.find_element_by_xpath("//*[@resource-id='container']/android.view.View[2]/android.view.View[1]").click()

 

(图6:爷爷元素定位到孙子元素)

五、通过AndroidUiAutomator定位元素(find_element_by_android_uiautomator)

  AndroidUIAutomator是一个强有力的元素定位方式,它是通过Android UIAutomator类库去找元素,可以选择id、name、className作为传入的字符串。有很多用法,类似xpath,也不一一贴图了。

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定位,如图7

#classname 复数定位,通过class定位某个商品
ui_class='new UiSelector().className("android.widget.RelativeLayout")' 
driver.find_element_by_android_uiautomator(ui_class[1]).click()

 

(图7:class复数定位)

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):模拟手指点击(最多五个手指),可设置按住时间长度(毫秒),如图8

- positions - list类型,里面对象是元组,最多五个。如:[(100, 20), (100, 60)]
    
- duration - 持续时间,单位毫秒,如:500
# tap坐标方式定位到运动
driver.tap([(720,72),(1080,216)],500)

 (图8:tap定位)

 

  好了,元素定位就讲完啦,下一节请期待....

 
posted @ 2020-04-20 22:05  一加一  阅读(2732)  评论(0编辑  收藏  举报