安卓python UI自动化 升级之代码进阶篇
安装及简易操作代码都在 这里
1. 等待机制:
查看代码
import time
from appium import webdriver
# 强制等待: 系统的等待机制
time.sleep(10) # 系统等待10s后继续执行
driver = webdriver.Remote('http://localhost:4723/wd/hub', {"自己配置dict"})
# 隐式等待: 全局的等待,每过一段事件就会去查看元素是否存在,最多等待10s后,找不到在抛出异常
driver.implicitly_wait(10)
# 显示等待
from selenium.webdriver.support.wait import WebDriverWait
"""详细格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver - WebDriver 的驱动程序(Ie, Firefox, Chrome 或远程)
timeout - 最长超时时间,默认以秒为单位
poll_frequency - 休眠时间的间隔(步长)时间,默认为 0.5 秒
ignored_exceptions - 超时后的异常信息,默认情况下抛 NoSuchElementException 异常。
WebDriverWai()一般由 until()或 until_not()方法配合使用,下面是 until()和 until_not()方法的说明。
until(method, message=’’)
调用该方法提供的驱动程序作为一个参数,直到返回值不为 False。
until_not(method, message=’’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 False。
lambda 提供了一个运行时动态创建函数的方法。
"""
# 对 negative ID 等待最多20s
WebDriverWait(driver, 20).until(lambda x: x.find_element(By.ID, "negative"))
driver.find_element(By.ID, "negative").click()
# 下面就是代码的try处理
try:
WebDriverWait(driver, 20).until(lambda x: x.find_element(By.ID, "negative"))
driver.find_element(By.ID, "negative").click()
except TimeoutException:
print("等待negative元素超时")
except NoSuchElementException as e:
print(e)
# 退出apium
driver.quit()
2. xpath详细解释
查看代码
# 如果元素text是唯一的,可以通过text文本定位
# //*[@text=‘text文本属性’]
driver.find_element(By.XPATH, "//*[@text='扫一扫']").click()
# 如果元素id是唯一的,也可以id属性定位
# //*[@resource-id=’id属性’]
driver.find_element(By.XPATH, "//*[@resource-id='com.taobao.taobao:id/tv_scan_text']").click()
# 也可以联合@resource-id属性和@text文本属性来下定位
driver.find_element(By.XPATH, "//*[@resource-id='com.taobao.taobao:id/tv_scan_text'][@text='扫一扫']").click()
# class属性唯一的话,同样可以通过class属性定位,有两种方法
driver.find_element(By.XPATH, "//android.widget.EditText").click()
driver.find_element(By.XPATH, "//*[@class='android.widget.EditText']").click()
# 通过content-desc属性定位
# //*[@content-desc=’desc的文本’]
driver.find_element(By.XPATH, "//*[@content-desc='帮助']").click()
""" 模糊定位 """
# contains模糊定位,对于一个元素的id或者text不是固定的,但有一部分是固定的,这种就可以模糊匹配。
# //*[contains(@content-desc, ‘帮助’)]
driver.find_element(By.XPATH, '//*[contains(@text, "注册/登录")]').click()
driver.find_element(By.XPATH, "//*[contains(@content-desc, '帮助')]").click()
driver.find_element(By.XPATH, "//*[contains(@class, 'EditText')]").click()
driver.find_element(By.XPATH, "//*[contains(@resource-id, 'id/home_searchedit')]").click()
"""组合定位"""
# 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()
""" 层级定位 """
# 如果一个元素,它除了class属性(class属性肯定会有),其它属性啥都没有,这种情况用上面方法就不适用了,这个时候可以找他父元素,通过父亲定位儿子
fa_sun = '//*[@resoure-id="com.taobao.taobao:id/home_searchbar"]/android.widget.EditText'
t = driver.find_element_by_xpath(fa_sun).click()
# 如果一个父元素下,有多个相同class的儿子时候,可以通过xpath的索引去取对应第几个,xpath是从1开始数的
fu_sun2 = '//*[@resource-id="com.taobao.taobao:id/ll_navigation_tab_layout"]/android.widget.FrameLayout[2]'
driver.find_element_by_xpath(fu_sun2).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)
"""通过层级关系,一层一层的往下找,同样可以通过爷爷元素,定位到孙子元素"""
# 自己研究以下吧,差不多的东西了
3. 安卓的手机按键,查看全部代码 可以完成键盘输入
查看代码
# 连接Appium服务器
driver = webdriver.Remote('http://localhost:4723/wd/hub', {"自己准备字典"})
# 模拟按下home键
driver.press_keycode(3)
# 按下返回键。
driver.press_keycode(4)
# 按下多任务键。
driver.press_keycode(187)
# 按下电源键。
driver.press_keycode(26)
# 按下音量加键。
driver.press_keycode(24)
# 按下音量减键。
driver.press_keycode(25)
# 截图键
driver.press_keycode(120)
# 设置输入法
driver.press_keycode(63)
# 手机自带浏览器
driver.press_keycode(64)
""" 联合操作 """
# 同时按下音量加键和电源键:
driver.press_keycode(24, 26)
# 同时按下音量减键和电源键
driver.press_keycode(25, 26)
def find_key():
""" 我按下一个键,去找按下后界面的元素是否存在,存在即 找到了,不存在即没找到,继续下一次按键 """
for i in range(200):
# 模拟按下0~200的键
driver.press_keycode(i)
print(i)
# 准备一个定位器
string = "com.coloros.recents:id/progress_bar"
try:
# 查找当前页面3s内是否存在 string 这个定位元素 这里用的是ID定位器
WebDriverWait(driver, 3).until(lambda x: x.find_element(By.ID, string))
# 找到这个元素后就退出
break
except:
# 未找到元素,先按下返回键,再按home键,返回桌面,继续找下一个键
driver.press_keycode(4)
driver.press_keycode(3)
time.sleep(1)
pass
# 执行返回操作
driver.back()
# 退出appium
driver.quit()
3. 多启动
查看代码
dic = {
'platformName': 'Android',
'platformVersion': '11',
'deviceName': 'myAndroid'
}
driver = webdriver.Remote('http://localhost:4723/wd/hub',dic)
# 打开APP1
driver.start_activity('cn.hyh.u3dproject', '.MainActivity')
time.sleep(2)
driver.find_element(MobileBy.ID,'cn.hyh.u3dproject:id/btnLogin').click()
# 打开APP2
driver.start_activity('com.jmar.xahl.ar.project', '.ui.activity.webview.WebViewActivity')
# 关闭当前操作的app,不会关闭驱动对象,只是把应用关闭,不会关闭驱动对象driver,当打印包名时,会有下面的结果
driver.close_app()
# 进入后台,5秒后再回到前台
driver.background_app(5)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!