大麦自动抢票从零上手:Appium 安卓链路一次跑通到提交订单
【免费下载链接】ticket-purchase大麦自动抢票,支持人员、城市、日期场次、价格选择项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase
抢一张热门票最难的不是"打开 App",而是开售那一秒内连续点掉七步:选城市、点购买、选票档、设数量、勾观演人、提交订单——手快的人靠肌肉记忆,脚本靠的是把这条链路固化成一段可重跑的 Python。ticket-purchase 干的就是这件事:你把手机停在演出详情页,开售时刻由脚本接管后面所有点击,你只管看结果。
先懂原理:Appium 安卓链路是怎么替你点屏的
在装任何东西之前,先花两分钟搞清楚"它凭什么能自己点",后面排错会顺很多。这条链路只有三个角色,各管一段:
| 角色 | 是什么 | 在这条链路里负责什么 |
|---|---|---|
大麦 App(包名cn.damai) | 你手机上装的购票 App | 真正的页面在这里:城市、场次、票档、提交按钮,全部渲染在它内部 |
| Appium | 架在电脑和手机之间的"遥控器" | 监听4723端口,把脚本说出的"点这里"翻译成设备能执行的触摸事件 |
| ADB(Android 调试桥) | 安卓官方的设备通信通道 | 负责电脑↔手机的底层握手:App 装没装、设备在不在线,都由它确认 |
串起来是这样一条传送带:Python 脚本发出指令 → Appium 服务(跑在你电脑上)接收 → 通过uiautomator2驱动下发 → 经由 ADB 打到手机 → 在大麦 App 的界面元素上落下一次真实触摸。所以它"自己点"不是玄学,而是它先找到目标控件在屏幕上的坐标,再按坐标点下去。理解了这一点,你就明白后面每个报错基本都是这条传送带的某一环断了。
零基础备料:一键自检 + 真机账号门槛
克隆下来第一件事不是跑脚本,而是自检。仓库里带了 check_environment.sh,它会逐项核对 Python、Node.js、Appium、Android SDK、ADB、设备连接和配置文件,每一项给出 ✅ 或 ❌,把缺的补上再进下一步:
git clone https://gitcode.com/GitHub_Trending/ti/ticket-purchase cd ticket-purchase ./check_environment.sh这个脚本是 shell 写的,贴合 macOS / Linux;Windows 用户改用 damai/check_environment.py 这套 Python 自检。
下面是完整的依赖底账,对照自查:
| 依赖 | 版本 / 状态 | 怎么装、怎么确认 |
|---|---|---|
| Python | 3.9+ | 运行抢票脚本本体 |
| Node.js | 20.19.0+ / 22.12.0+ / 24.0.0+ | Appium 的运行底座,node --version查看 |
| Appium | 3.1.0+ | npm install -g appium |
| uiautomator2 驱动 | 需单独装 | appium driver install uiautomator2 |
| Android SDK | 已设ANDROID_HOME | 管理设备通信,随 Android Studio 提供 |
| adb | 随 SDK 自带 | adb devices看设备是否device态 |
| 大麦 App | 已安装 + 已登录 + 观演人已登记 | 提交订单的硬前提,包名cn.damai |
两个新手最容易栽的坑,先记下来:
- 脚本里的示例路径是作者机器上的。start_appium.sh、start_ticket_grabbing.sh、check_environment.sh 都硬编码了作者 Mac 上的 SDK 目录(
/Users/shengwang/Library/Android/sdk)和 Python 解释器路径。跑之前要把这些对齐到你本机的 SDK 目录和你的 Python,否则第一条命令就会路径报错。 - 设备必须真的在线。
adb devices里序列号后面应是device;若是offline,真机去查 USB 调试开关,模拟器用adb shell getprop sys.boot_completed确认它是否完全启动(返回1才算就绪)。
config.jsonc 配置:把目标票喂给脚本的最快方法
移动端的全部行为,都由 damai_appium/config.jsonc 这一个文件驱动。把目标演出填进去,就等于把"要抢哪张票"告诉脚本:
{ "server_url": "http://127.0.0.1:4723", "keyword": "歌手或巡演名", "users": ["观演人1", "观演人2"], "city": "深圳", "date": "12.06", "price": "内场1199元", "price_index": 5, "if_commit_order": false }详情页上的城市、场次、票档三行,和city、date、price三组字段是一一对应的。下面这张标注图把"页面上看到哪一格 → 改哪个字段"标了出来:
逐字段拆解,重点是一个反直觉的字段:
| 字段 | 作用 | 新手注意 |
|---|---|---|
server_url | Appium 服务地址 | 换了端口要同步改 |
keyword | 搜索关键词 | 填歌手名 / 巡演名 |
users | 观演人姓名数组 | 与账号登记逐字一致;票的数量也按它的人数来 |
city | 城市站 | 支持模糊匹配,"深圳"能命中"深圳站" |
date | 场次日期 | 形如12.06(移动端是 MM.DD,不是完整日期) |
price | 票档文字描述 | 只给人眼核对,不参与点击 |
price_index | 票档索引 | 真正瞄准目标的那个数,从 0 计数 |
if_commit_order | 是否自动提交订单 | 首次运行保持false空跑 |
price_index为什么才是关键。新版大麦 App 里,票档区域的文本是空串"",按文字去找按钮的老办法已经失效。脚本因此改成按位置来:先定位票档容器project_detail_perform_price_flowlayout,再取其中第price_index个"可点击的 FrameLayout"去点。索引从 0 开始,5就是从上往下第 6 个档位。所以price这个字段看着像票档,其实只负责让你确认没选错行;真正决定点哪一格的,是price_index。开抢前从上往下重新数一遍票档,把索引对齐,这是最省心的校验。
另外两件事脚本替你办了:users写几个人,数量就点几次加号(len(users) - 1次);city走三级匹配——先精确、再包含、最后 XPath 兜底,所以城市名不必写全。
不想走 App 端,仓库里还有一套 Selenium 的 Web 端兜底实现(damai/ 目录),它读的是 damai/config.json,字段定义见 damai/config.py,target_url填详情页地址、users/city/dates分别对应观演人、城市与场次,配置长这样:
开售那一刻:双终端分工、Appium 常驻与 3 次重试
把运行过程按时间线走一遍,你就知道两个终端和手机各在哪一刻登场:
终端一跑
./start_appium.sh:先export ANDROID_HOME,确认设备在线、cn.damai已安装,然后appium --port 4723常驻。这个窗口全程别关,关了就等于遥控器没电了。手机:打开大麦 App → 搜到目标演出 → 停在详情页。未开售时底部按钮是"预约",开售后变"立即购买",两种文案脚本都认,所以停在详情页等就行,搜索环节不用管。
终端二跑
./start_ticket_grabbing.sh:先用curl http://127.0.0.1:4723/status确认 Appium 活着、再确认 config.jsonc 存在,回显keyword/city/users供你核对,输入y进入。脚本接管(入口 damai_appium/damai_app_v2.py),按这个顺序连点:
① 选城市 精确 → 包含 → XPath 三级匹配 ② 点购买按钮 "预约 / 购买 / 立即" 任一文案都能命中 ③ 选票档 按 price_index 点票档区第 N 个可点击 FrameLayout ④ 设数量 按 users 人数点加号 (len(users) - 1) 次 ⑤ 确定购买 btn_buy_view,兜底"确定 / 购买" ⑥ 勾观演人 按 users 姓名收集坐标后,几乎一次性全部点完 ⑦ 提交订单 if_commit_order 为 true 才真正提交失败不认命:整条流程最多重试 3 轮,每轮间隔 2 秒,并且每轮都重新初始化驱动(
_setup_driver)。单次卡顿或某一步没点到,不会直接判负,下一轮重来。
零基础自救手册:常见报错的 现象 → 原因 → 怎么修
排错时按"现象 → 原因 → 怎么修"对号入座,比从头读文档快得多。
Appium 拒绝启动,提示 Node 版本不兼容
- 现象:要求 Node 至少
^20.19.0 || ^22.12.0 || >=24.0.0,本地过旧。 - 原因:Node 版本低于 Appium 门槛。
- 怎么修:升级 Node(如
brew upgrade node),再重跑自检确认版本落在兼容区间。
报Neither ANDROID_HOME nor ANDROID_SDK_ROOT
现象:脚本说找不到 SDK。
原因:两个环境变量都没设。
怎么修:
export ANDROID_HOME=/你的/android/sdk路径 export ANDROID_SDK_ROOT=/你的/android/sdk路径写进
~/.bashrc或~/.zshrc让下次登录仍在,同时别忘把启动脚本里那处硬编码示例路径换成你自己的 SDK 目录。
提示找不到活动设备 /Unable to find an active device
- 现象:Appium 拿不到设备。
- 原因:设备处于离线态,或模拟器没完全启动。
- 怎么修:跑
adb devices看状态列,应为device;offline就查 USB 调试,模拟器用adb shell getprop sys.boot_completed确认返回1。
连接被拒绝Connection refused
- 现象:抢票脚本连不上 Appium。
- 原因:终端一的服务已经停了,或端口被别的进程占用。
- 怎么修:确认终端一的
start_appium.sh还开着,再用curl http://127.0.0.1:4723/status验证端口;端口被占就换端口,并同步改server_url。
点到的票档不是想要的
- 现象:选错了档位。
- 原因:索引从 0 计数,且页面票档顺序可能因活动而异。
- 怎么修:打开详情页票档区从上往下重数,把
price_index对齐后再开跑,别凭印象填。
用之前想清楚的边界:合规、频率与风险
工具能帮你把那几步点得快,但它改变不了"票就那么多、所有人同时抢"这个事实。开跑前把这几条想透:
- 不承诺"必中"。脚本只压缩了你的手速,不能保证一定抢到;热门场次该难抢还是难抢。
- 遵守大麦网使用条款。自动化工具属于平台使用条款关注的范围,别拿它做高频并发刷单,也别用别人的账号或观演人信息——观演人姓名必须是你账号下真实登记、且与证件一致的。
- 尊重其他购票者的机会。把自动化当成"替自己点得快一点",而不是"挤掉别人"的手段,控制频率、别起多开并发。
- App 会更新,选择器会失效。新版票价文本变空串、只能改用
price_index,就是活例子;大麦升级界面后,控件 ID 和文案可能跟着变,脚本点不动时先核对选择器,而不是盲目重试。 - 风控有真实存在的可能,请自行评估并只在你愿意负责的账号上使用,网络保持稳定。
开抢前最后过一遍:环境自检通过、脚本里的示例路径已对齐本机、price_index已重数对齐、观演人姓名逐字一致、curl .../status能正常响应、手机停在详情页且已登录;确认开售时间,开抢前才把if_commit_order改为true,之前一律保持false空跑,确认流程无误再上。
愿它替你省下那一秒的犹豫,也愿你抢到的那张票,是自己真正想看的演出。
【免费下载链接】ticket-purchase大麦自动抢票,支持人员、城市、日期场次、价格选择项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考