如何用 Python 实现安卓机自动化?
昨天晚上十一点多,我在公司楼下抽烟,真困得半死,我们组那个小李突然在群里喊:“东哥,有没有啥办法,让我手机每天早上自己点开 APP 点两下就完事儿?我不想天天五点半爬起来打卡了。” 我当时看了一眼他那张睡眼惺忪的自拍,心想:这玩意儿用 Python 搞个安卓自动化不就完了嘛。
就顺着这个事儿跟你们唠一唠,怎么用 Python 把安卓手机“变成脚本”。
大概就是三件事:
电脑能连上手机,能发命令(靠的是 adb,那串命令行大家应该都见过)。 Python 能在电脑上执行这些命令,或者调用现成的库。 手机那边帮你把“点击、滑动、输入文字”这些动作做出来。
你可以把这套东西想象成:Python → ADB → 手机,Python 是老板,adb 是中间的翻译,手机就是干活的打工人。 之前我搞数据库压测时,也是用脚本去怼数据库的,只不过那会儿老板是 JMeter,这次换成 Python 而已。
先把环境整好,不然后面全是玄学报错
小李当时一上来就问:“我是不是得 root ?要不要刷机?” 我说你先别把手机搞砖了,普通自动化根本用不到。
你需要这些:
一部安卓机(尽量是自己机型,别拿女朋友手机乱试,出了问题不好解释…) 数据线一根 电脑上装好 Python 3.8+(越新越省心) 手机打开开发者模式 + USB 调试 电脑上装好 adb(装个 Android Platform Tools 就有)
手机那一步你应该很熟: 设置 → 关于手机 → 连续点版本号 N 下,弹出“你已处于开发者模式”。 然后回到设置里搜“开发者选项”,打开“USB 调试”。
电脑这边,确认 adb 有效,终端里敲:
adb devices
能看到类似:
ZX1Gxxxxxxxx device
那就算通了。如果显示 unauthorized,就看手机上是不是弹了个“是否允许 USB 调试”,点允许就行。
先玩一圈“土法自动化”:Python + adb + 坐标点击
我一般教别人,会先从最土的办法开始,这样你能直观感受到“我真的是在操控手机”,而不是黑盒瞎碰。
Python 里直接调用 adb 命令,其实就是用 subprocess:
import subprocess
defadb(cmd: str) -> None:
full_cmd = f"adb {cmd}"
print("执行命令:", full_cmd)
result = subprocess.run(full_cmd, shell=True, capture_output=True, text=True)
if result.stdout:
print("输出:", result.stdout)
if result.stderr:
print("错误:", result.stderr)
# 唤醒屏幕 + 解锁(简单粗暴版)
adb("shell input keyevent 26") # 电源键
adb("shell input swipe 300 1000 300 300 300") # 上滑解锁(数值按你手机分辨率改)
# 按坐标点击(x, y)
deftap(x: int, y: int):
adb(f"shell input tap {x}{y}")
# 在某个输入框输入文字
definput_text(text: str):
# 注意空格要转义
text = text.replace(" ", "%s")
adb(f"shell input text '{text}'")
# 示例:点击屏幕中间,并输入一段话
tap(540, 960)
input_text("hello_android")
你可以随便打开一个聊天框、记事本之类的,然后跑这个脚本,看它自动给你敲字。 坐标咋来的?最粗暴的办法:开一个“开发者选项”里的“指针位置”,你手指点一下,就看到 X/Y 坐标了,记下来。
这个方式有两个硬伤:
手机分辨率变了,坐标就全废了。 页面稍微变动一下(比如弹了个弹窗),脚本直接点错地方。
所以这个只能算“入门感受一下”,真要上生产(哪怕是你个人每天打卡),建议还是用“根据元素定位”的方式。
别急着上高级库,先封装一下自己的“小遥控器”
我自己一般会先把这些 adb 命令封装成一个类,这样过几天再看,不至于一堆字符串看不懂。
import subprocess
from typing import Optional
classAndroidDevice:
def__init__(self, serial: Optional[str] = None):
self.serial = serial
def_adb(self, cmd: str):
prefix = f"adb -s {self.serial} "if self.serial else"adb "
full_cmd = prefix + cmd
print("[ADB]", full_cmd)
result = subprocess.run(full_cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print("命令失败:", result.stderr)
return result.stdout.strip()
defwake(self):
self._adb("shell input keyevent 26")
defswipe(self, x1, y1, x2, y2, duration_ms=300):
self._adb(f"shell input swipe {x1}{y1}{x2}{y2}{duration_ms}")
deftap(self, x, y):
self._adb(f"shell input tap {x}{y}")
definput_text(self, text: str):
text = text.replace(" ", "%s")
self._adb(f"shell input text '{text}'")
defstart_app(self, pkg: str, activity: str = None):
if activity:
self._adb(f"shell am start -n {pkg}/{activity}")
else:
self._adb(f"shell monkey -p {pkg} -c android.intent.category.LAUNCHER 1")
defhome(self):
self._adb("shell input keyevent 3")
if __name__ == "__main__":
phone = AndroidDevice()
phone.wake()
phone.swipe(300, 1000, 300, 300)
phone.home()
phone.start_app("com.android.settings")
这样你就有了一个最基础的“遥控器”。 比如你每天早上要打开某个打卡 APP,就可以把包名填进去,脚本一跑它自动帮你打开。
真正常用的玩法:用 uiautomator2 通过“控件”来操作
上面这些都是靠“坐标”点的,特别脆。 稍微靠谱一点的做法,是像写 Web 自动化那样,通过“元素”来点,比如“找到 text 是 ‘登录’ 的按钮,然后点击它”。
安卓上比较常用的一个库叫 uiautomator2,Python 版也很成熟,装起来:
pip install --upgrade pip
pip install uiautomator2
然后,手机插着电脑,命令行执行:
python -m uiautomator2 init
它会帮你把手机上必要的辅助服务装好,中间手机上可能弹权限框,一路点允许。
跑通之后,就可以在 Python 里这么写:
import uiautomator2 as u2
# 连接手机,默认 USB
d = u2.connect() # 或者 u2.connect("设备序列号")
print("设备信息:", d.info)
# 启动一个应用,比如设置
d.app_start("com.android.settings")
# 等一会儿,等页面出来
d.wait_timeout = 10.0
# 举例:点击包含“应用”的设置项,注意不同机型文案不一样
d(textContains="应用").click()
# 滑动一下
d.swipe(0.5, 0.8, 0.5, 0.2) # 用相对坐标,更通用
# 找搜索框输入点啥
search = d(resourceIdMatches=".*search.*")
if search.exists:
search.click()
d.send_keys("微信", clear=True)
你会发现,这一套写起来跟 Web 自动化特别像——都是“找元素 → 点 → 输入”。
uiautomator2 支持的定位方式挺多的,例如:
text="登录":按文本等于textContains="登录":文本包含resourceId="com.xxx:id/btn_login"className="android.widget.Button"description="更多":按 content-desc
你可以用它自带的可视化工具,或者配合 “uiautomatorviewer”、adb shell uiautomator dump 加 grep 去看页面上的控件信息,不过这个就有点展开聊不完了。
随便来个完整小例子:自动打开某个 APP 做一串操作
举个轻松一点的,不搞什么“代打卡”,就假设你有个“记账 APP”,每天想自动点进去,切到某个 tab,帮你点一下“新增”。
代码大概这样:
import time
import uiautomator2 as u2
PKG = "com.example.budget"# 替换成你自己的包名
defmain():
d = u2.connect()
print("已连接:", d.device_info)
# 亮屏 + 解锁(简单模式)
ifnot d.info.get("screenOn", True):
d.screen_on()
time.sleep(1)
# 如果有锁屏图案/密码,这里就有点复杂了,就不展开了
d.app_start(PKG)
d.wait_timeout = 10.0
# 等主界面加载,大部分 App 主按钮都有 text 或 desc
if d(text="记一笔").exists:
d(text="记一笔").click()
elif d(description="记一笔").exists:
d(description="记一笔").click()
else:
print("没有找到记一笔按钮,可能 UI 改了")
return
# 输入金额
amount_input = d(resourceIdMatches=".*amount.*")
if amount_input.exists:
amount_input.click()
d.send_keys("25.50", clear=True)
# 选分类
if d(text="餐饮").exists:
d(text="餐饮").click()
# 保存
if d(text="保存").exists:
d(text="保存").click()
else:
print("没找到保存按钮")
# 退回桌面
time.sleep(1)
d.press("home")
if __name__ == "__main__":
main()
你可以把这段脚本丢到一个 .py 文件里,每天让计划任务(Windows 任务计划程序 / Linux crontab)去跑一次,整个操作你都不用碰手机。
再高级一点的话题,比如多设备管理、截图识别、图像找点
有的人会问:“东哥,我能不能用图片识别去点某个按钮?因为 text 也不稳定。”
可以的,一般会用到:
uiautomator2的截图功能:img = d.screenshot() # 得到一个 PIL.Image 对象然后配合
opencv-python、aircv去做模板匹配,找到那个按钮在屏幕上的位置,再用d.click(x, y)去点。
这个就像打游戏脚本一样,识别血条、识别按钮。但这一块容易越界到一些灰色地带的场景,我就不具体写代码了,你自己玩玩就好。
总之啊,用 Python 控制安卓,其实没你想的那么玄学,就是:
把 adb 用熟 选个顺手的库(像 uiautomator2) 按“人怎么点手机”那一套动作,一步步翻译成代码
你可以从最简单的开始,比如:
自动打开一个 App 自动发一条固定内容的消息给自己 自动每天开机后检查一下某个设置有没有被还原
等你写顺手了,再去玩更复杂的流程,别一上来就想把整条业务线全自动化,那真的容易把自己绕进去。
行,我这会儿先去泡杯咖啡,你要是有具体的场景(比如“帮我写个脚本自动打开 X App 干 Y 事”),你直接丢出来,我帮你把那段 Python 挑一挑、补全就行。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB