把大麦抢票做成流水线:Python 双端自动化实践
【免费下载链接】ticket-purchase大麦自动抢票,支持人员、城市、日期场次、价格选择项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase
ticket-purchase 是基于 Python 的大麦自动抢票工具,用 Selenium 与 Appium 双平台驱动,自动完成登录、选场次票价、勾选观演人与提交订单,开票瞬间交给自动化抢票脚本。
开票几秒钟,手速赢不了
热门演出开票时,页面上的购买按钮从灰变亮、再到"缺货",往往只有几秒。人眼看到、手伸过去、点中、再选场次选票价,这一串动作每步都有固定开销,网络一拥堵就被进一步放大,所以手动抢票在热门场次里基本靠运气。
还有一个容易被忽略的事实:大麦的大部分票源只在 App 端开售,网页端只覆盖部分演出。这正是 ticket-purchase 同时做两端、且以安卓端为主线的原因。
脚本凭什么比手速快:原理与环节耗时
速度优势不来自"点得快",而来自缩短链路、去掉等待:
- 轮询代替盯屏:脚本按短间隔持续检测购买按钮状态,亮起的瞬间触发点击,省去人的反应环节。
- 坐标原生点击:移动端 v2 版本先取元素中心坐标,再用
mobile: clickGesture完成一次约 50 毫秒的 tap,并把waitForIdleTimeout等等待项设为 0。 - 批量勾选观演人:先一次性收集所有观演人坐标,再连续点击,避免逐个查找元素。
- 内置重试:点击或定位失败不会中断,而是按配置反复尝试。
- 显式短等待:用 2 秒的
WebDriverWait替代 5 秒的全局隐式等待。
各环节的量级差异大致如下(具体数值取决于网络与机器配置):
| 方式 | 触发机制 | 开售到提交的大致耗时 | 主要瓶颈 |
|---|---|---|---|
| 纯手动 | 人眼看到按钮亮起后手动点 | 0.2 秒~1 秒以上 | 反应时间与网络拥堵 |
| Selenium 抢票(Web) | 脚本轮询按钮状态 | 0.1 秒~0.3 秒 | 部分演出网页端不开售 |
| Appium 抢票(移动端) | 坐标原生点击 + 重试 | 0.05 秒~0.2 秒 | 设备或模拟器性能 |
📱 跑起来的完整路径:环境、自检与启动
第一步,取代码并自检环境:
git clone https://gitcode.com/GitHub_Trending/ti/ticket-purchase cd ticket-purchase ./check_environment.shcheck_environment.sh 会依次检查 Python、Node.js(要求 20.19 以上)、Appium、Android SDK、adb、是否有设备在线、大麦 App 是否已安装(核对cn.damai包名)、4723 端口服务是否存活,最后回显配置里的关键词、城市与观演人。缺什么都会直接给出对应的安装命令,不用自己翻文档。
移动端抢票还需要一次性的环境准备:
npm install -g appium appium driver install uiautomator2Web 端只需安装 Python 依赖(Selenium 锁定 4.18.1,ChromeDriver 会自动下载):
pip install -r damai/requirements.txt一条真实抢票时间线:周深深圳站
以仓库自带的 damai_appium/config.jsonc 为例(关键词"周深"、城市"深圳"、日期"12.06"、票价"内场1199元"、索引 5),完整时间线如下:
| 时刻 | 发生了什么 |
|---|---|
| T-1h | 环境自检通过,先用一场非热门演出完整试跑一遍流程 |
| T-15min | ./start_appium.sh拉起服务;模拟器打开大麦,搜索"周深",停在深圳站详情页 |
| T-5min | 配置与页面对账:城市、日期、票价文案与索引和页面显示逐项一致 |
| T0 | ./start_ticket_grabbing.sh启动,开售瞬间脚本检测到购买按钮亮起并点击 |
| T+3s | 场次、票价(第 5 个索引)、2 名观演人被批量勾选,订单自动提交 |
脚本需要停在的详情页长这样:
人在这条时间线里只做一件事——开售前把 App 停在演出页,其余环节都由脚本接管。
⚙️ 配置参数逐项说明
移动端配置在 damai_appium/config.jsonc,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 服务地址和端口,默认 4723。keyword:在 App 里搜演出的关键词。users:观演人名单,姓名必须与账号里登记的完全一致。city:演出页面上的城市文案,要和页面显示完全一致,不能用简称。date:场次日期,"月.日"格式,如 12.06。price:目标价位文案,主要供人工核对用。price_index:目标价位在列表中的索引,从 0 开始。App 改版后页面上票价 Text 变为空串,v2 版本改用索引定位,这是最容易被配错的一项。if_commit_order:订单确认页加载后是否自动提交订单。
配置项与页面元素的对应关系决定了成败,任何一项对不上,脚本都会点到按钮却选不对价位:
Web 端配置在damai/config.json,字段略有不同:index_url、login_url、target_url分别指定首页、登录页和目标演出页;dates与prices是数组,支持"2026-04-11""4月11日"等多种写法的模糊匹配;if_listen控制是否监听缺货登记;max_retries(默认 1000)控制轮询重试上限;fast_mode(默认开启)缩短等待时间,官方标注可提速 40%~75%;page_load_delay(默认 2 秒)是订单确认页的加载等待。
目录与核心文件
ticket-purchase/ ├── damai/ # Web 端(Selenium) │ ├── damai.py # 主程序:配置校验、选座、提交流程 │ ├── concert.py # 演唱会业务逻辑 │ ├── config.py # 配置类 │ └── requirements.txt # Python 依赖 ├── damai_appium/ # 移动端(Appium) │ ├── damai_app_v2.py # 优化版主程序,推荐使用 │ ├── damai_app.py # 初版实现 │ ├── config.py # 配置加载 │ └── config.jsonc # 移动端配置 ├── tests/ # pytest 测试套件 ├── check_environment.sh # 环境自检 ├── start_appium.sh # 启动 Appium 服务 └── start_ticket_grabbing.sh # 启动抢票两个主程序各自管一个端:
- damai/damai.py:Selenium 抢票入口,流程为配置校验、打开页面、选场次与票价、勾选观演人、重试提交;成功后页面保留 5 分钟供人工确认。
- damai_appium/damai_app_v2.py:Appium 抢票入口,包含前文提到的全部提速策略,并打印执行进度;实现细节可在 damai_appium/app.md 里查到。
🧯 常见报错与排查
| 报错信息 | 原因 | 处理办法 |
|---|---|---|
| Node version must be at least ^20.19.0 ... | Node 版本过低 | macOS 用brew upgrade node,或用 nvm 切换到兼容版本 |
| Neither ANDROID_HOME nor ANDROID_SDK_ROOT ... | SDK 环境变量未导出 | 在~/.zshrc或~/.bashrc里加export ANDROID_HOME=... |
| Unable to find an active device or emulator | 设备未连接或未被识别 | 确认 USB 调试已开,adb devices核对,adb kill-server && adb start-server重启服务 |
| Connection refused | Appium 未启动或 4723 被占用 | lsof -i :4723找出占用进程,curl http://127.0.0.1:4723/status验证恢复 |
| 城市、价位选不上 | 配置文案与页面不一致 | 逐字核对 city、date、price;price_index 确认从 0 计数 |
Web 端另有两类退出提示:config.json语法错误、缺少必填字段(如target_url)时,damai.py 会打印缺少的字段名并直接退出,按提示补齐即可,不会静默失败。
进阶:多设备协同、回流票与调参
- 双端双保险:同一场演出,两台机器分别跑 Web 端与移动端,覆盖"网页端不开售"的场次。
- 多移动设备:不同网络(有线 + 4G 热点)下跑多个模拟器实例,互不干扰。
- 回流票:开售后 30 分钟到 2 小时内常有退票回流。移动端没有独立的监听参数,持续守候靠内置重试循环实现,让脚本常驻、等它轮询命中即可;Web 端则可用配置里的
if_listen开关监听缺货登记。 - 调参方向:弱网时降低
max_retries、拉长轮询间隔;强网时保持fast_mode开启、把page_load_delay压到 1 秒,让订单确认页更快落地。
收尾:先合规,再一键启动
项目声明仅供学习和研究使用,请勿用于商业用途。使用时遵守大麦的服务条款与平台规则,练习建议用专用账号,网络保持稳定,并在开售前完成全部环境准备。
开售前检查三件事:环境自检通过、App 停在目标演出页、配置与页面逐项对过账。然后:
./start_appium.sh # 终端 1:拉起 Appium ./start_ticket_grabbing.sh # 终端 2:启动大麦抢票脚本 # Web 端 cd damai && python damai.py剩下的,交给脚本。
【免费下载链接】ticket-purchase大麦自动抢票,支持人员、城市、日期场次、价格选择项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考