大麦自动抢票实战:我用手边的安卓机,搭了一个全天候盯票机器人
大麦自动抢票实战:我用手边的安卓机,搭了一个全天候盯票机器人
【免费下载链接】ticket-purchase大麦自动抢票,支持人员、城市、日期场次、价格选择项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase
大麦自动抢票一直是技术圈里热度不减的话题——热门场次开售即罄,手动刷新拼不过手速和网速。我研究并跑通了一套基于 Python 与 Appium 的开源方案(另有 Selenium 的 Web 端实现),用一台安卓机挂机盯票,从城市、场次、票价到观演人自动全选,实测把"开售瞬间"的成功率提了几个量级。这篇文章记录我的完整实操过程,包括配置里那些没人告诉你的坑。
抢了三次没抢到,我决定写个程序替我点
先说背景。为了给朋友抢一场演唱会门票,我提前半小时坐在电脑前,把身份证号、观演人信息全部预填好,就等开售那一秒。结果呢?倒计时一结束,页面卡了十几秒,等我能点到"立即购买",看到的已经是"缺货登记"。同一晚试了三场,全军覆没。
后来我复盘了一下手动抢票的死穴:
| 手动操作的瓶颈 | 实际影响 |
|---|---|
| 页面加载 + 人脑反应 | 开售头 2 秒基本抢不到 |
| 频繁刷新被风控 | 越刷越慢,甚至要验证码 |
| 观演人逐个勾选 | 选完人票早没了 |
| 单点单设备 | 失败一次就要从头再来 |
于是我开始找现成方案,最终锁定这个项目:ticket-purchase。它把两条路都给你铺好了——Web 端用 Selenium 驱动 Chrome,适合电脑前蹲守;移动端用 Appium 控制安卓设备上的大麦 APP,适合挂机。我两套都跑了,移动端体验更稳,下面也以它为主线讲。
获取代码很简单:
git clone https://gitcode.com/GitHub_Trending/ti/ticket-purchase cd ticket-purchase开工前先跑一遍"体检":check_environment.sh 到底查了什么
这个项目贴心的点是:它把环境检查写成了一个脚本。你不需要逐条手动验证,直接跑:
./check_environment.sh它会像体检一样逐项排查,一项不过就会亮红灯并告诉你怎么办:
- Python 是否安装(要求 3.9+)
- Node.js 是否安装、版本是否够新(项目要求 20.19.0+ 或 22.12.0+,
>=24也行) - Appium 是否全局安装(要求 3.1.0+)
- Android SDK 路径是否存在(脚本里硬编码了
~/Library/Android/sdk,macOS 用户一般就是这个位置) - ADB 是否可用
- 是否有安卓设备连接(模拟器或真机)
- 大麦 APP(包名
cn.damai)是否已安装 - Appium 服务器(
http://127.0.0.1:4723)是否在跑 damai_appium/config.jsonc配置文件是否存在
把需要准备的东西列成一张清单,照着准备就行:
| 组件 | 要求 | 验证命令 |
|---|---|---|
| Python | 3.9+ | python3 --version |
| Node.js | 20.19.0+ | node --version |
| Appium | 3.1.0+ | appium --version |
| Android SDK | 配置好环境变量 | adb devices |
| 大麦 APP | 已登录账号 | adb shell pm list packages \| grep damai |
我当时的体检结果:Node 版本太低(18),appium直接装不上驱动。升级之后重跑,全绿。
真正决定生死的,是 config.jsonc 里那几行
环境是地基,但决定你能不能抢到票的,是配置文件。移动端的配置在 damai_appium/config.jsonc,长这样:
{ "server_url": "http://127.0.0.1:4723", "keyword": "周深", "users": [ "王胜", "潘鸿运" ], "city": "深圳", "date": "12.06", "price": "内场1199元", "price_index": 5, "if_commit_order": true }每个参数的含义,我整理成了一张表:
| 参数 | 含义 | 填写要点 |
|---|---|---|
server_url | Appium 服务地址 | 本地默认http://127.0.0.1:4723,不用改 |
keyword | 搜索关键词 | 填艺人名/演出名,如"周深" |
users | 观演人名单 | 必须与大麦账号里的实名观演人逐字一致,顺序就是勾选顺序 |
city | 演出城市 | 要与页面上的城市文案完全匹配 |
date | 演出日期 | 按页面显示的格式写,如"12.06" |
price | 票价描述 | 页面显示什么就抄什么,如"内场1199元" |
price_index | 票价索引 | 从 0 开始,这是最容易踩的坑 |
if_commit_order | 是否自动提交订单 | true全自动;false停在确认页让你人工复核 |
配置时的关键点,是把参数和 APP 页面上的元素一一对应起来。页面长什么样、哪个数字对应哪个票价,项目文档里有一张标注图可以对着看:
这里必须单独讲一下price_index的坑。项目作者在代码注释里写得很直白:票价列表里某些档位的文字是隐藏的,直接按文案找会失败,所以脚本换了个思路——在票价容器里按索引定位FrameLayout,要求它clickable=true。也就是说,price_index填的是"第几个可点击的票价框",而不是"第几档票价"。比如页面从上到下第 6 个可点击框,就填5。我第一次就是没搞懂这个,填成了页面上的档位序号,结果每次都点到错误票价,直到对着 damai_appium/damai_app_v2.py 里的注释才恍然大悟。
机器人是怎么"点点点"完成抢票的
配置填好,环境就绪,接下来就是重头戏——看它怎么自动跑完整条抢票链路。核心逻辑在 damai_appium/damai_app_v2.py,主流程run_ticket_grabbing有清晰的七步:
选择城市 → 点击预约按钮 → 选择票价 → 调整数量 → 确定购买 → 勾选观演人 → 提交订单下面这张流程图是整个系统的全局视图,从登录到提交订单的分支都画出来了:
具体执行时,有几处设计值得说道说道:
1. 每个关键步骤都准备了备用选择器。大麦 APP 的页面经常改版,按钮文字可能从"立即购买"变成"立即预订"。脚本用smart_wait_and_click把多个选择器排队试:先按 UI 元素 ID 找,找不到就按文字正则匹配.*预约.*|.*购买.*,再不行就按 XPath 模糊匹配。相当于给每个按钮买了三份保险。
2. 用坐标点击代替元素点击,快一个数量级。这是它高性能的核心。ultra_fast_click拿到元素后不直接.click(),而是取出元素矩形坐标算中心点,再调mobile: clickGesture以极短时长(50ms)点下去,绕过了 Selenium/Appium 那一堆等待和确认逻辑。抢票场景下,这几十毫秒的差距就是有票和没票的差距。
3. 观演人是批量快点的。勾选多个观演人是手动抢票最耗时的一步。脚本用ultra_batch_click先把所有用户的坐标一次性收集好,再以 10ms 间隔连续点,全程不到 0.1 秒。
4. 整个流程套了重试壳。run_with_retry(max_retries=3)会在失败后自动重连驱动再来一轮,间隔 2 秒,相当于给你留了两次"复活"机会。
跑完一圈,控制台会打出每步的执行结果和总耗时。我实测从选城市到提交订单,顺利时 3 秒内完事。这是脚本运行时的票务页面:
我踩过的坑,希望你绕开
配置对、脚本也熟,不代表万事大吉。把我在真机上遇到的坑和官方文档里的常见问题汇总一下,按排查顺序排好:
坑一:Node 版本不兼容
Error: Node version must be at least ^20.19.0 || ^22.12.0 || >=24.0.0升级到兼容版本即可:
brew upgrade node坑二:安卓设备连不上
Error: Unable to find an active device or emulator先看设备状态,再重启 ADB:
adb devices # 有没有 device 前缀 adb shell getprop ro.build.version.release # 安卓版本 adb kill-server && adb start-server项目里的启动脚本 start_appium.sh 会顺带检查模拟器和大麦 APP,没检测到会直接给出启动模拟器的完整命令。
坑三:Appium 服务器连接被拒
Error: Connection refused先确认服务活着没:
curl http://127.0.0.1:4723/status项目也帮你兜底了:抢票脚本 start_ticket_grabbing.sh 启动前会用 curl 探一次 4723 端口,没跑就提示你先执行./start_appium.sh。
坑四:抢到一半报"点击失败"
大多是页面结构变了或者元素没加载出来。我的经验是:先看控制台日志里是哪一步失败,再对着 damai_appium/damai_app_v2.py 里对应的选择器,用 Appium Inspector 确认新页面上的真实 ID/文案,改掉那一处选择器就行。
另外提一句登录:移动端是"设备里已登录的大麦 APP + 你手动进到演出详情页",脚本只负责后面的操作,所以开抢前务必确认 APP 登录态有效,别在最后关头弹个登录页。
进阶玩法:多设备协同、回流票监控与几句提醒
把单机跑通只是起点。真正热门的场次,我建议这样布局:
| 设备角色 | 配置侧重 | 用途 |
|---|---|---|
| 主控设备 | 快速模式、重试拉满 | 开售瞬间主攻 |
| 备用设备 | 标准配置 | 主设备失败后顶替 |
| 监听设备 | 开启回流监控 | 蹲守退票回流 |
如果你蹲的是不定时释放的回流票,Web 端有个专门的监听开关:if_listen。开了之后脚本会持续轮询票态,看到"缺货登记"就说明还没票,继续等;看到可抢按钮立刻下手。配合max_retries调大(比如 10000),可以挂一整天不歇。Web 端的配置和主程序在 damai/config.json 与 damai/damai.py,登录走 Cookie 机制,首次扫码后会存成damai_cookies.pkl复用。
想再压榨一点性能,可以把安卓动画关掉,减少渲染延迟:
adb shell settings put global window_animation_scale 0 adb shell settings put global transition_animation_scale 0 adb shell settings put global animator_duration_scale 0最后是几句过来人提醒:网络尽量用有线,系统时间务必与北京时间同步(差一秒就可能错过开售节点),账号建议用专门的小号而不是主号,脚本只在开售前后必要的时间段运行。这套系统本质是把你从重复劳动里解放出来——技术可以帮你抢到票,但也请守住合理使用的边界,别影响其他观众正常购票。
祝你下次开售,一次成功。
【免费下载链接】ticket-purchase大麦自动抢票,支持人员、城市、日期场次、价格选择项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
