新手避坑指南:用Python+uiautomator2写第一个安卓自动化脚本(附贴吧实战)
Pythonuiautomator2安卓自动化实战从零编写贴吧签到脚本第一次接触安卓自动化测试时我盯着满屏的adb命令和陌生的Python库名发呆了半小时。直到在模拟器上看到机械臂自动完成贴吧签到、滑动浏览、点赞回帖的全过程才意识到自动化脚本就像给手机装上了数字手指——精准、不知疲倦且可复现。本文将带你绕过我踩过的所有坑用最轻量的uiautomator2工具链完成第一个真正可用的自动化脚本。1. 环境配置避开90%新手的安装陷阱1.1 工具链的极简选择开发安卓自动化脚本需要四个核心组件Python 3.8推荐使用Miniconda管理环境Android Debug Bridge (ADB)版本需≥1.0.41uiautomator2Python库与手机端服务的桥梁Weditor可视化元素定位器安装时常见的版本冲突问题# 错误示范混用pip和conda安装 conda create -n u2 python3.8 pip install uiautomator2 # 可能引发库冲突 # 正确做法纯pip环境 python -m venv u2_env source u2_env/bin/activate pip install --upgrade pip wheel1.2 ADB连接的魔鬼细节当执行adb devices显示unauthorized时按此流程排查在手机开发者选项中撤销USB调试授权重新插拔USB线或重启模拟器确保电脑端没有多个adb进程# 查看并杀死残留adb进程 tasklist | findstr adb taskkill /F /PID 进程ID实测发现夜神模拟器需要特殊处理进入安装目录的nox_adb.exe执行adb kill-server后用nox_adb.exe connect 127.0.0.1:62001连接2. 元素定位Weditor可视化实战技巧2.1 解析百度贴吧的UI层次打开Weditor后按F5刷新界面层级会看到类似XML的结构node index3 text同意 resource-idcom.baidu.tieba:id/agree classandroid.widget.TextView/三种最可靠的定位方式对比定位方式示例代码适用场景resource-idd(resourceIdcom.baidu.tieba:id/agree)官方APP规范开发时首选textd(text同意)按钮文字固定时descriptiond(description确定按钮)无障碍标签完善时2.2 动态等待策略元素加载需要智能等待而非固定sleep# 设置全局隐式等待单位秒 d.implicitly_wait(10) # 显式等待特定元素更精准 d(text同意).wait(timeout15) # 最长等15秒 d(text同意).wait_gone(timeout5) # 等待元素消失3. 脚本编写贴吧自动化全流程实现3.1 启动与权限处理完整处理隐私弹窗的代码模板import uiautomator2 as u2 def handle_privacy_popup(d): try: if d(text同意).exists: d(text同意).click() print(已处理隐私弹窗) elif d(text我知道了).exists: d(text我知道了).click() except Exception as e: print(f权限处理异常: {str(e)}) # 连接设备 d u2.connect(emulator-5554) d.app_start(com.baidu.tieba) handle_privacy_popup(d)3.2 滑动与点击的工程化实践贴吧引导页滑动的防呆设计def swipe_through_guide(d, swipe_count3): width, height d.window_size() for _ in range(swipe_count): # 从右向左滑动起始点X坐标取屏幕宽度的80% d.swipe(width*0.8, height/2, width*0.2, height/2, 0.5) d.sleep(1) # 滑动后稳定等待 # 点击立即体验 if d(description立即体验按钮).exists: d(description立即体验按钮).click() else: d.xpath(//*[text立即体验]).click()3.3 签到功能的完整实现自动判断签到状态的逻辑def tieba_sign(d, tieba_name): # 进入指定贴吧 d(resourceIdcom.baidu.tieba:id/btn_search).click() d(resourceIdcom.baidu.tieba:id/et_search_keyword).set_text(tieba_name) d.press(enter) # 处理签到按钮 if d(text签到).exists: d(text签到).click() print(f【{tieba_name}】签到成功) elif d(text已签到).exists: print(f【{tieba_name}】今日已签) else: print(f【{tieba_name}】未找到签到按钮) # 返回主页 d.press(back)4. 异常处理与性能优化4.1 常见崩溃场景应对编写健壮脚本需要处理的异常元素定位超时增加wait timeout并添加重试机制应用无响应定期检查d.app_current()状态内存泄漏每10次操作后重启APP示例重试装饰器from functools import wraps import time def retry(max_attempts3, delay1): def decorator(func): wraps(func) def wrapper(*args, **kwargs): attempts 0 while attempts max_attempts: try: return func(*args, **kwargs) except Exception as e: print(fAttempt {attempts1} failed: {str(e)}) attempts 1 time.sleep(delay) raise RuntimeError(fFailed after {max_attempts} attempts) return wrapper return decorator retry(max_attempts5) def safe_click(element): element.click()4.2 提升执行速度的秘诀通过对比测试发现uiautomator2比Appium快约30%还可通过以下方式优化禁用动画在开发者选项中关闭所有动画缩放减少截图避免频繁使用d.screenshot()批处理命令使用d.xpath(//*).all()一次性获取元素速度对比实测数据执行相同贴吧操作操作步骤uiautomator2耗时(ms)Appium耗时(ms)启动APP12001800处理弹窗500800完成签到30004500总耗时47007100在小米10上实测发现uiautomator2的点击响应延迟稳定在80-120ms之间而Appium存在200-300ms的波动。当需要处理列表滚动等复杂操作时这种差异会指数级放大。