1 u2自动化工具基本操作-操作设置
import uiautomator2 as u2
# 通过wifi链接
d = u2.connect_wifi('192.168.1.8')
# 查看设备信息
# print(d.device_info)
print(d.service('uiautomator').running())
# 通过start方法启动uiautomator服务
d.service('uiautomator').start()
time.sleep(2)
print(d.service('uiautomator').running())
# 停止服务
d.service('uiautomator').stop()
time.sleep(2)
print(d.service("uiautomator").running())
# 查看atx-agent的运行状态,如果atx-agent真的停止了,我们可以通过connect来唤醒atx-agent
print(d.agent_alive)
# 查看设备信息
print(d.device_info)
# 查看设备的分辨率
print(d.window_size)
#查看获取到的wifi地址
print(wlan_ip)
2 u2自动化工具基本操作-操作app
import uiautomator2 as u2
d = u2.connect_use('设备号')
# 通过app_install方法安装apk,url='xxx.apk'
d.app_install(url="http://file.mukewang.com/apk/app/125/1609297863/imooc_8.0.0_10102001_android.apk")
# 启动app
# 包名使用aapt dump badging apk路径
d.app_start(package_name="cn.com.open.imooc")
# 获取当前前台运行的app信息
print(d.app_current())
# 关闭app
d.app_stop("cn.com.open.mooc")
# 或者app详细信息
print(d.app_info(pkg_name='cn.com.open.mooc'))
# 清除app缓存
d.app_clear('cn.com.open.mooc')
# 卸载app
d.app_uninstall('cn.com.open.mooc')
# 获取移动设备中所有app的信息
print(d.app_list())
# 获取所有正在运行的app的信息
print(d.app_list_running())
# 停止所有app的运行
d.app_stop_all()
# 卸载所有app,卸载所有第三方app,u2项目包不会被卸载
d.append_uninstall_all()
3 APP activity和控件,weditor工具的安装
Activity:
activity是用户和应用程序交互的窗口,一个activity相当于我们实际中的一个网页
控件:
TextView:显示文字
TextView显示文字 EditText输入框,可编辑
lmageView显示图片Button按钮 CheckBox复选框 RadioButton单选按钮
weditor
基于python实现的查看客户端元素的工具
pip install weditor -i https://pypi.doubanio.com/simple
4 weditor工具介绍和常见问题
安装好weditor之后再命令行中键入
weditor
在浏览器中打开下图中的url
手机中打开电脑管家,将atx和uiautomator设置为自启动
5UiSelector文本定位方式
获取包名:
我们除了通过aapt的方式获取包名,还可以通过下面的方式
手动点开app,然后再weditor中点击空白处,在界面中就可以看见包名了
Text文本选取方式
text 全文本匹配
textContains 文本包含
textMatches正则表达式
textStartsWith 起始文本
代码示例
import uiautomator2 as u2
d = u2.connect_usb('XMKDU19403004799')
# d.app_start(package_name='com.android.settings')
# 全文本匹配,点击
d(text = "设置").click()
d(text="更多连接").click()
# 文本包含
d(textContains="更多").click()
# 传入正则表达式
d(textMatches=".{2}连接").click()
# 通过文本的起始
d(textStartsWith="无线").click()
6 UiSelector class定位方式
className选取方式
className classname匹配
classNameMathces className正则表达式匹配
# class定位
# 在weditor中获取到元素的className之后,去右边Coding下的Hierarch中搜一下,将当前帧布局中该元素的序号填入instakce
d(className="android.widget.TextView", instance=5).click()
# 通过正则表达式表示classname
d(classNameMatches = 'android.widget.\w*',text="蓝牙").click()
7 UiSelector resourceld定位方式
# 通过resourceId的方式进行定位
# instance就是id的索引,也可以像列表一样携带d后括号的后面去
d(resourceId="android:id/title", instance=6).click()
# 通过正则表达式的方式
d(resourceId="android:id/.{5}", instance=6).click()
# 可以多条件限定,比如加上一个文本选择方式
d(resourceId="android:id/title", textContains="显示").click()
8 Uiautomator 混合定位方式
# 混合定位
d(className="androidx.recyclerview.widget.RecyclerView").child(text="蓝牙").click()
# 完全链式定位方法,代码非常冗长(不建议使用)
d(className="android.widget.LinearLayout").child(resourceId="com.android.settings:id/dashboard_tile")[2].child(className="android.widget.LinearLayout").click()
# 多种方式限定
d(className = "android.widget.LinearLayout").child_by_text('蓝牙', resourceId="android:id/title").click()
# 通过兄弟节点定位(不建议使用)
d(className='android.widget.LinearLayout').sibling(className="android.widget.LinearLayout", instance=3).click()
9 坐标定位方式
在WEditor中点击坐标,有两种坐标定位方式,一种是坐标,一种是长宽的百分比的方式
d.click(0.272, 0.495)
10 控件操作和控件超时
# 控件不存在,我们要咋办
# 找不到空间,抛异常UiObjectNotFoundError
d(text="蓝牙1").click(timeout=3)
# click_exists() 找不到就跳过
d(text="绿牙").click_exists(timeout=2)
# 在操作时间,判断元素是否在页面中存在
print(d(text="红牙").exists(timeout=3)) # False
print(d(className="androidx.recyclerview.widget.RecyclerView").child(
resourceId="com.android.settings:id/dashboard_tile").count)
for view in d(className="androidx.recyclerview.widget.RecyclerView").child(
resourceId="com.android.settings:id/dashboard_tile"):
print(view.info)
11 通过U2实现移动设备九宫格解锁
import uiautomator2 as u2
d = u2.connect_usb('XMKDU19403004799')
# 息屏
d.screen_off()
# 点亮屏幕
d.screen_on()
# 点亮屏幕并解锁
d.unlock()
# 获取屏幕状态
print(d.info.get('screenOn'))
# 回到主屏幕
d.press("home")
# 按返回按钮
d.press("back")
# 屏幕向左滑动
d.swipe_ext('left')
# 屏幕向右滑动
d.swipe_ext('right')
# 解锁九宫格,points是连线的坐标,duration就是每个点之间的时间
d.swipe_points(points=[
(0.224,0.393),
(0.222,0.393),
(0.212,0.393),
(0.156,0.393),
(0.753,0.393),
],duration=0.2)
12 Xpath定位方式
先再chrome中安装xpath helper
import uiautomator2 as u2
d = u2.connect_usb('XMKDU19403004799')
print(d.info)
# 获取当前空间的源代码(xml)
print(d.dump_hierarchy())
# 通过xpath定位(直接去WEditor中复制即可)
d.xpath('//*[@text="蓝牙"]').click()
13 u2登录考研帮并执行部分操作
import time
import uiautomator2 as u2
class HandleKaoYanBang:
def __init__(self):
self.package_name = 'com.tal.kaoyan'
self.d = u2.connect_usb('XMKDU19403004799')
self.d.app_clear(self.package_name)
time.sleep(4)
self.size = self.get_windowsize()
self.handle_watcher()
def handle_watcher(self):
"""定义一个监控器"""
# 监控器会单独的起一个线程
# 用户隐私协议
self.d.watcher.when(xpath='//*[@resource-id="com.tal.kaoyan:id/tip_commit"]').click()
# 权限
self.d.watcher.when(
xpath='//*[@resource-id="com.android.permissioncontroller:id/permission_allow_button"]').click()
# 广告条跳过
self.d.watcher.when(xpath='//*[@resource-id="com.tal.kaoyan:id/tv_skip"]').click()
# 监控器写好之后,要通过start方法启动
self.d.watcher.start()
def get_windowsize(self):
"""获取手机屏幕大小"""
return self.d.window_size()
def close_app(self):
self.d.watcher.stop() # 关闭监控器
self.d.app_stop(self.package_name)
self.d.app_clear(self.package_name)
def handle_kaoyanbang_app(self):
"""启动考研帮app,并实现自动化操作"""
self.d.app_start(package_name='com.tal.kaoyan')
# 再点击之气那需要判断是狗有这个控件
self.d(text="密码登录").click_exists(timeout=10)
# 输入账户
self.d(resourceId='com.tal.kaoyan:id/login_email_edittext').set_text('18321112937')
# 输入密码
self.d(resourceId="com.tal.kaoyan:id/login_password_edittext").set_text("18321112937..")
# 点击登录
self.d(resourceId="com.tal.kaoyan:id/login_login_btn").click_exists(timeout=3)
# 点掉过年广告弹框
self.d(resourceId="com.tal.kaoyan:id/view_wemedia_cacel").click_exists(timeout=10)
self.d(resourceId="com.tal.kaoyan:id/kaoyan_home_schtip_close").click_exists(timeout=10)
# 操作
# 在10秒中之内如果界面启动了
if self.d.wait_activity('.ui.activity.HomeTabActivity', timeout=10):
self.d(text="研讯").click_exists(timeout=10)
# 获取屏幕的中心点
# 获取y周远方点,获取y轴近点
x1 = int(self.size[0]) * 0.5
y1 = int(self.size[1]) * 0.9
y2 = int(self.size[1]) * 0.15
while True:
# toast是安卓系统的一个信息提示操作
if self.d.toast.get_message(0) == "内容已经全部加载完了":
self.close_app()
return
self.d.swipe(x1, y1, x1, y2)
if __name__ == '__main__':
k = HandleKaoYanBang()
k.handle_kaoyanbang_app()