1. 项目概述与核心价值最近在搞安卓应用测试特别是那些重度依赖用户交互的App比如短视频平台手动点点点不仅效率低还容易出错。我就琢磨着能不能用Python写个脚本让它像真人一样去操作手机自动刷视频、点赞、评论这其实就是自动化测试里模拟用户行为的一个典型场景。经过一番折腾我发现ADBAndroid Debug Bridge配合Python的subprocess模块是实现这个想法最直接、最轻量的方案完全不需要引入Appium这样的大型框架特别适合快速验证功能、执行重复性任务或者做一些简单的数据采集。这个方案的核心价值在于“轻快准”。轻是指环境依赖少基本上有Python和ADB工具就行快是指脚本开发调试速度快ADB命令直通系统底层响应迅速准是指对屏幕坐标、组件属性的控制精度高能模拟出非常接近真人的操作序列。对于测试工程师、爬虫开发者或者任何需要批量操作安卓手机的朋友来说掌握这套方法就相当于拥有了一支不知疲倦的“数字手指”能7x24小时替你完成那些枯燥的点击和滑动。接下来我就以让脚本自动刷某个视频App为例拆解整个从环境搭建到脚本优化的实战过程。2. 环境准备与核心工具解析工欲善其事必先利其器。在开始写代码之前我们需要把“战场”布置好。这里主要涉及两样东西Python环境和ADB工具链。别看听起来简单里面有不少细节直接决定了后续脚本的稳定性和可移植性。2.1 Python环境与必要库Python是我们的指挥中枢。我强烈建议使用Python 3.7及以上的版本因为它在异步支持和标准库稳定性上更好。不需要安装什么特殊的自动化测试框架核心就用Python自带的subprocess库来调用ADB命令。当然为了让代码更优雅我们可以安装Pillow库来处理截图用opencv-python来做简单的图像识别进阶需求用schedule库来做定时任务。但最基础的版本只需要Python本身。注意如果你电脑上有多个Python版本务必确认你使用的pip和python命令指向的是同一个版本。在命令行输入python --version和pip --version查看避免库装错了地方。安装核心辅助库的命令很简单pip install Pillow schedule至于opencv-python因为体积较大且安装可能遇到问题我们初期可以先不装用更简单的坐标定位法。2.2 ADB工具配置详解ADB是谷歌官方提供的安卓调试桥它是我们与手机通信的“电缆”。配置ADB有三步下载ADB工具包最简单的方法是下载Android SDK Platform-Tools。你可以去安卓开发者官网找或者在一些可靠的软件下载站搜索“Platform-Tools rxx.x.x”。下载后得到一个文件夹里面就有adb.exeWindows或adbMac/Linux。配置系统环境变量这是为了让你的Python脚本或命令行在任何位置都能调用adb命令。将上一步中adb工具所在的目录路径添加到系统的PATH环境变量中。添加完成后打开一个新的命令行窗口输入adb version如果能看到版本号信息说明配置成功。连接手机并开启调试模式用USB数据线连接安卓手机和电脑。在手机上进入【设置】-【关于手机】连续点击“版本号”7次开启“开发者选项”。然后进入【开发者选项】找到并开启“USB调试”。首次连接时手机会弹出“允许USB调试吗”的对话框勾选“始终允许”并确认。连接成功后在电脑命令行输入adb devices。如果看到设备列表中出现你的设备序列号后面跟着device字样而不是unauthorized恭喜你通道已经打通了。实操心得很多连接问题出在驱动上。如果adb devices显示unauthorized检查手机端的授权弹窗如果设备根本不在列表里可能是电脑缺少对应的USB驱动可以去手机厂商官网下载对应的驱动安装。使用一些第三方手机助手软件有时也能自动安装好驱动。3. 核心思路与ADB命令精讲我们的目标是模拟用户。用户刷视频App的核心动作无非是启动App、滑动屏幕、点击点赞/评论、偶尔点进详情页。对应到ADB命令我们需要掌握几个最关键的“武器”。3.1 控制逻辑Python如何驱动ADBPython通过subprocess模块来执行系统命令。基本模式是subprocess.run([‘adb’, ‘shell’, ‘具体的手机端命令’], capture_outputTrue, textTrue)。这样Python就能获取到ADB命令执行后的结果进而做判断和决策。整个脚本的逻辑就是一个**“感知-决策-执行”**的循环通过ADB获取当前屏幕信息感知根据预设规则判断该做什么决策再发送相应的ADB操作命令执行。3.2 必备ADB命令库下面这些命令是我们脚本的基石务必理解其用法和输出。模拟点击input tap x y这是最常用的命令。x和y是屏幕坐标。坐标原点(0,0)在屏幕左上角。你需要先获取要点击位置的坐标。模拟滑动input swipe x1 y1 x2 y2 [duration(ms)]模拟从点(x1, y1)滑动到点(x2, y2)。可选的duration参数表示滑动过程持续的毫秒数值越大滑动越慢。刷视频上滑通常用这个。模拟按键input keyevent 键值例如input keyevent 4模拟返回键input keyevent 3模拟Home键input keyevent 26模拟电源键。键值表可以网上搜索“Android keyevent code”。启动应用am start -n 包名/活动名这是启动App的关键。包名是应用的唯一标识活动名是应用启动的第一个界面。获取方式打开目标App然后在电脑命令行输入adb shell dumpsys window | findstr mCurrentFocusWindows或adb shell dumpsys window | grep mCurrentFocusMac/Linux。输出类似mCurrentFocusWindow{... com.ss.android.ugc.aweme/com.ss.android.ugc.aweme.splash.SplashActivity}那么com.ss.android.ugc.aweme就是包名com.ss.android.ugc.aweme.splash.SplashActivity就是活动名。获取当前屏幕截图screencap -p /sdcard/screen.png将当前屏幕截图保存到手机存储。然后可以用adb pull /sdcard/screen.png .命令拉到电脑上分析。获取屏幕分辨率wm size输出类似Physical size: 1080x2340。这个信息至关重要因为坐标是相对于分辨率的。如果你的脚本要在不同分辨率的手机上运行就需要根据这个分辨率来动态计算坐标比例。注意事项不同手机厂商的ROM可能对ADB命令的支持有细微差异。例如有些手机需要额外的权限才能执行input命令。如果遇到命令无效的情况可以尝试在命令前加上adb shell并以root权限执行如果手机已root。但大多数情况下开启USB调试后上述基础命令都是可用的。4. 实战构建自动刷视频脚本理论说得再多不如动手写一遍。我们以模拟刷短视频为例构建一个基础脚本。这个脚本会完成打开App不断上滑刷新视频随机间隔点赞运行一段时间后自动停止。4.1 脚本框架与基础函数封装首先我们把常用的ADB操作封装成Python函数让主逻辑更清晰。import subprocess import time import random import os def run_adb_command(cmd): 执行ADB命令并返回结果 # 注意这里cmd应该是一个列表例如 [adb, shell, input, tap, 500, 1000] result subprocess.run(cmd, capture_outputTrue, textTrue, shellTrue) return result.stdout.strip() def get_screen_resolution(): 获取手机屏幕分辨率 output run_adb_command([adb, shell, wm, size]) # 输出示例Physical size: 1080x2340 if x in output: resolution output.split(:)[-1].strip() width, height map(int, resolution.split(x)) return width, height else: print(无法获取分辨率使用默认值 1080x2340) return 1080, 2340 def tap_screen(x, y): 在指定坐标(x, y)模拟点击 run_adb_command([adb, shell, input, tap, str(x), str(y)]) def swipe_up(duration300): 从屏幕底部中央向上滑动模拟刷视频 width, height get_screen_resolution() start_x width // 2 start_y height * 4 // 5 # 起始点在屏幕下方4/5处 end_x start_x end_y height // 5 # 结束点在屏幕上方1/5处 run_adb_command([adb, shell, input, swipe, str(start_x), str(start_y), str(end_x), str(end_y), str(duration)]) def launch_app(package, activity): 启动指定的应用程序 run_adb_command([adb, shell, am, start, -n, f{package}/{activity}]) def take_screenshot(filenamescreen.png): 截取手机屏幕并拉到电脑当前目录 phone_path f/sdcard/{filename} run_adb_command([adb, shell, screencap, -p, phone_path]) run_adb_command([adb, pull, phone_path, .]) print(f截图已保存为 {filename})4.2 核心循环逻辑与行为模拟接下来我们编写主函数将上述操作串联成一个自动化流程。def main(): # 1. 准备工作 print( 安卓自动刷视频脚本启动 ) screen_width, screen_height get_screen_resolution() print(f检测到屏幕分辨率: {screen_width}x{screen_height}) # 以某短视频App为例包名和活动名需要根据实际情况替换 # 获取方法见上文 3.2 节 app_package com.ss.android.ugc.aweme app_activity com.ss.android.ugc.aweme.splash.SplashActivity # 2. 启动App print(f正在启动 {app_package}...) launch_app(app_package, app_activity) time.sleep(5) # 等待App完全启动 # 3. 定义点赞坐标示例坐标需根据你的手机和App界面调整 # 点赞按钮通常位于屏幕右侧。这里假设在 (屏幕宽度-100, 屏幕高度/2) 附近 like_button_x screen_width - 100 like_button_y screen_height // 2 # 4. 主循环刷视频 total_swipes 50 # 计划刷的视频数量 swipe_count 0 try: while swipe_count total_swipes: print(f\n--- 第 {swipe_count 1} 个视频 ---) # 随机观看一段时间模拟真人阅读 watch_time random.uniform(3, 8) print(f观看中... ({watch_time:.1f}秒)) time.sleep(watch_time) # 随机决定是否点赞30%概率 if random.random() 0.3: print(f执行点赞 ({like_button_x}, {like_button_y})) tap_screen(like_button_x, like_button_y) time.sleep(0.5) # 等待点赞动画 # 上滑刷到下一个视频 print(上滑到下一个视频) swipe_up(duration400) # 400毫秒的滑动比较自然 swipe_count 1 # 随机间隔避免过于规律 interval random.uniform(1, 3) time.sleep(interval) except KeyboardInterrupt: print(\n用户中断脚本执行。) finally: print( 脚本运行结束 ) if __name__ __main__: main()4.3 坐标获取与适配技巧脚本里最头疼的就是坐标(like_button_x, like_button_y)怎么定。硬编码的坐标换台手机或者App界面改版就失效了。这里分享两个方法开发者选项-指针位置在手机【开发者选项】里开启“指针位置”。屏幕上会显示当前触摸点的坐标。你手动点一下点赞按钮就能看到坐标值。把这个值填到脚本里。这是最准确的方法。截图比例计算先手动截图adb shell screencap拉到电脑上用画图软件打开鼠标悬停在点赞按钮上看软件显示的坐标。这个坐标是基于截图图片的。然后你需要根据手机真实分辨率和截图图片分辨率进行等比换算。公式是真实X (图片X / 图片宽度) * 手机真实宽度。实操心得对于固定位置的按钮如点赞、评论、分享用方法一获取一次坐标即可。但为了脚本的健壮性最好能写一个坐标配置文件针对不同分辨率预设几套坐标方案脚本运行时根据检测到的分辨率自动选择。5. 进阶让脚本更智能与健壮基础脚本只能按固定坐标操作很脆弱。要让它更接近真人更稳定我们需要引入一些进阶策略。5.1 基于图像识别的元素定位初阶完全依赖坐标会“刻舟求剑”。我们可以用图像匹配来寻找按钮。比如我们提前保存一个“点赞爱心”的小图标like_icon.png。每次操作前先截取当前屏幕然后在截图中寻找这个图标的位置。这里我们可以使用opencv-python的模板匹配功能。虽然安装稍麻烦但定位精度和适应性高很多。import cv2 import numpy as np def find_icon_on_screen(icon_path, threshold0.8): 在手机当前屏幕中查找图标 :param icon_path: 图标模板图片路径 :param threshold: 匹配阈值0.8表示80%相似度以上认为匹配 :return: 匹配区域的中心坐标 (x, y)未找到返回None # 1. 获取当前屏幕截图 take_screenshot(current_screen.png) screen_img cv2.imread(current_screen.png) icon_img cv2.imread(icon_path) # 2. 进行模板匹配 result cv2.matchTemplate(screen_img, icon_img, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(result) # 3. 判断是否匹配成功 if max_val threshold: icon_h, icon_w icon_img.shape[:2] center_x max_loc[0] icon_w // 2 center_y max_loc[1] icon_h // 2 print(f找到图标置信度{max_val:.2f}中心坐标({center_x}, {center_y})) return center_x, center_y else: print(f未找到图标最高置信度{max_val:.2f}) return None # 在主循环中使用 like_icon_center find_icon_on_screen(like_icon.png) if like_icon_center: tap_screen(like_icon_center[0], like_icon_center[1]) else: print(未找到点赞按钮可能界面已变化执行上滑跳过。) swipe_up()5.2 异常处理与流程恢复自动化脚本最怕遇到意外网络卡顿导致界面加载慢、弹出广告、手机锁屏等等。我们必须让脚本具备一定的容错和自我恢复能力。def safe_operation(operation_func, *args, max_retries3, **kwargs): 带重试机制的安全操作 for i in range(max_retries): try: result operation_func(*args, **kwargs) return result except Exception as e: print(f操作失败 (尝试 {i1}/{max_retries}): {e}) time.sleep(2) # 等待后重试 if i max_retries - 1: print(操作重试多次仍失败执行恢复流程。) # 恢复流程例如按一次返回键然后重新尝试 run_adb_command([adb, shell, input, keyevent, 4]) # 返回键 time.sleep(2) raise # 或者执行其他恢复逻辑 # 在主循环中将关键操作包裹起来 try: safe_operation(swipe_up, duration400) except Exception as e: print(f上滑操作最终失败: {e}) # 更激进的恢复回到桌面再重新打开App run_adb_command([adb, shell, input, keyevent, 3]) # Home键 time.sleep(2) launch_app(app_package, app_activity) time.sleep(5)5.3 多设备管理与并发控制如果你有多台测试机可以同时运行脚本。关键在于为每台设备指定ADB命令。连接多台设备后adb devices会列出多个序列号。执行命令时需要加上-s 序列号参数。device_serial 你的设备序列号 def run_adb_command_for_device(cmd, serial): # 在命令中插入 -s 参数 full_cmd [adb, -s, serial] cmd result subprocess.run(full_cmd, capture_outputTrue, textTrue, shellTrue) return result.stdout.strip()你可以写一个设备列表然后用concurrent.futures库的ThreadPoolExecutor来并发执行任务效率倍增。6. 常见问题排查与优化实录在实际操作中你肯定会遇到各种坑。下面是我踩过的一些以及解决办法。6.1 ADB连接不稳定或设备离线现象脚本运行一段时间后adb devices显示设备offline或者命令无响应。排查检查USB线劣质或接触不良的USB线是罪魁祸首换一根原装或质量好的线。检查电源管理有些电脑USB口会休眠在设备管理器中禁用USB选择性暂停设置。重启ADB服务在命令行执行adb kill-server然后adb start-server。重新插拔手机物理重连有时能解决驱动层面的临时故障。优化在脚本关键节点如循环开始加入连接状态检查如果发现设备离线尝试自动重启ADB服务。6.2 坐标点击无效或错位现象input tap命令执行了但手机没反应或者点错了地方。排查坐标计算错误确认获取坐标的方法是否正确。使用“指针位置”功能最可靠。屏幕旋转如果手机屏幕旋转了坐标体系会变。可以在脚本开始时用adb shell settings put system accelerometer_rotation 0锁定旋转或用adb shell dumpsys display | grep mCurrentOrientation获取当前方向来动态计算。导航栏/状态栏有些坐标计算是否包含了状态栏的高度全屏应用和普通应用的坐标原点可能不同。优化采用基于图像识别的定位方法从根本上避免对绝对坐标的依赖。6.3 脚本被系统或App杀死现象脚本在后台运行一段时间后自动停止。排查手机省电策略在手机设置中将你使用的Python IDE如PyCharm或命令行工具以及目标测试App加入“后台无限制”或“电池优化白名单”。App后台活动限制有些安卓系统会严格限制后台App的活动。确保测试App在前台运行。优化让脚本定时模拟一些轻微操作如轻微移动一下鼠标或按一下音量键防止系统判定为无活动。6.4 操作频率过快被识别为机器人现象App弹出验证码或直接限制账号功能。排查你的操作间隔太规律、太快不像真人。优化随机化所有等待时间time.sleep都用random.uniform(a, b)生成一个区间内的随机值。加入人性化抖动在滑动操作中加入微小的轨迹偏移而不是完美的直线。模拟复杂手势偶尔模拟长按、双击等操作。控制总时长不要7x24小时不间断运行模拟人类的作息运行几小时就休息一段时间。这套Python ADB的自动化方案其魅力在于用极简的工具组合实现了强大的自动化能力。它可能没有Appium那样全面的元素定位和跨平台能力但在执行速度、资源占用和对系统底层控制的直接性上有着无可比拟的优势。对于固定流程的重复任务、竞品体验测试、或者一些轻量级的爬虫场景它都是一个高效而优雅的选择。最关键的是整个开发和调试过程非常直观所见即所得能让你快速获得正反馈并深入理解安卓应用的交互本质。