Python抢票脚本实战:从requests登录到自动下单 📅 发布时间:2026/9/9 9:41:44 👁 浏览次数: 简介针对演唱会抢票这一高频场景资源内含自动化抢票脚本与配套说明文档面向有一定编程基础、希望系统掌握爬虫、多线程、定时任务等实战技能的开发者。压缩包共两个文件分别是py脚本和txt说明脚本覆盖模拟登录、并发请求、定时触发和异常处理等关键环节说明文档交代运行环境、依赖库及基本使用流程。包体仅6KB轻量易用。目前已有1065人学习下载。通过该案例可以直观理解请求库与解析库在数据抓取中的配合方式学习多线程与多进程在并发场景下的取舍并掌握利用定时任务库实现到点自动执行的方法代码中体现的Cookies与会话维持、验证码处理思路以及日志输出习惯也可迁移到其他自动化项目中是提升Python工程能力的实用参考。 不少朋友应该经历过这种场面开票前一分钟页面上的按钮还灰着倒计时一过你疯狂点鼠标结果永远被卡在“排队中”。我也一样手速拼不过别人之后干脆写了一套Python抢票脚本从登录到下单前前后后调试了两周最后帮着抢到两张内场票。这篇文章就把我的完整思路、代码结构和踩坑记录一起分享出来算是一个真实的Python实战项目复盘。先说清楚这不是什么黑科技也不是教你绕过平台规则的灰色操作。Python在这里做的事情本质上是把“盯倒计时、刷余票、选场次、点提交”这些重复动作固化成程序让脚本比人手更快、更稳定。文章会涉及Python安装、requests请求、Cookie登录、轮询与异常处理等知识点适合有点Python基础、想做一个完整实战项目的读者参考。用之前一定先看平台的用户协议个人学习、自己抢票没问题但千万别拿它去干破坏公平购票的事。如果你连Python环境都还没装好建议先去官网下载Python 3.10以上版本安装时记得勾选“Add Python to PATH”装完在命令行敲一下python --version能输出版本号再继续往下看。1. 为什么有人能用Python抢到票先理清抢票的本质1.1 手动抢票为什么拼不过脚本很多人觉得抢票是拼网速、拼手速其实更准确地说是拼“做重复动作的速度”。人的反应时间通常在200到300毫秒鼠标移动到指定位置、确认场次、选择票档、勾选观演人再点提交整套流程至少需要一两秒。而脚本通过网络请求发出指令在同等网络条件下可以达到毫秒级甚至可以在开票瞬间同时完成多次尝试。另一个关键点在于手动抢票时页面要先渲染、加载JavaScript、等图片资源真实看到按钮能点击的时候其实已经比最原始的数据慢了很多。Python脚本可以直接请求后端接口跳过大量页面渲染时间。很多平台开票后会先“锁库存”这时候谁先提交订单谁就大概率锁住票。脚本的优势不在于“聪明”而在于省掉了所有不必要的中间步骤。1.2 一条门票订单背后的完整请求链路要写抢票脚本就得先搞明白从打开页面到支付成功系统里到底发生了什么。我以自己调试过的流程为例大致可以分成几步打开演唱会详情页拿到基本场次信息点击“立即购买”进入选票档和观演人页面系统加载余票状态判断当前是否可购提交订单平台锁定库存跳转支付订单状态变为待支付。其中真正的关键节点只有两个余票查询接口和提交订单接口。前者负责告诉脚本“什么时候有票”后者负责把票锁到你的名下。其他步骤比如页面渲染、倒计时动画、选座动画都只是交互层的装饰。理解了这一点Python抢票脚本的核心就变成了两件事以合理的频率轮询余票接口一旦发现有余票立刻用携带好的用户身份信息去提交订单。1.3 抢票脚本的基本策略基于上面的链路我的脚本策略非常简单提前登录保持会话提前选好目标场次和票档开票前几分钟开始轮询检测到余票后立刻下单如果提交失败根据错误信息决定是重试还是停下来人工处理。这套逻辑不需要机器学习也不需要造什么复杂模型大部分情况下用requests和基本的异常处理就够了。还有一个容易忽略的点抢票脚本的成功率不只取决于“快”还取决于“稳”。比如请求超时要重试接口返回异常要记录日志提交订单后要确认是否真的锁单成功。很多半路失败的脚本问题不是不够快而是一次请求报错后直接崩溃或者重复提交导致订单异常。所以后续所有代码我都围绕这个最小可用流程来展开。2. 环境准备从Python安装到依赖选型2.1 基础环境与虚拟环境配置写Python抢票脚本的第一步是准备一套干净、可控的开发环境。Python版本我建议用3.10以上有些旧的加密库在3.7上已经跑得不太稳没必要给自己添堵。安装完成后最好给项目单独建一个虚拟环境避免系统里乱七八糟的包互相影响。在项目目录下执行python -m venv venvWindows环境下激活虚拟环境用venv\Scripts\activatemacOS和Linux用source venv/bin/activate。激活后命令行前面会出现(venv)前缀代表你正在独立环境里工作。这一步看起来简单但能帮你省掉很多依赖冲突的问题。接下来安装项目需要用到的库。我最初只装了一个requests后面调试时又加上了fake-useragent用来随机生成User-Agent以及loguru用来打印带时间的日志。安装命令就一行pip install requests fake-useragent loguru我一直建议不要在一开始就把所有可能用到的库全装上做到哪一步需要什么再装什么这样你对每个依赖的作用会更清楚。2.2 requests、selenium、playwright到底怎么选这是很多新手第一个卡住的地方。网上关于抢票的教程有人用selenium模拟浏览器点击有人用playwright自动打开页面也有人用requests直接请求接口。我的结论是优先用requests不到万不得已不要碰浏览器自动化。做个简单对比方案优点缺点适用场景requests直接请求接口请求体积小、执行快、资源占用低需要手动分析接口和构造参数能抓到接口且登录态好处理时首选selenium模拟浏览器不需要分析接口直接用页面元素定位启动慢、容易被风控识别、维护麻烦页面复杂或接口加密难解时兜底playwright模拟浏览器自动化能力更强、支持多浏览器同样有被识别风险体积大需要稳定调试浏览器交互时使用我当时先试过selenium发现每次启动浏览器都要浪费好几秒而且打开真实页面后还要等动态加载抢票高峰期很容易被“排队等待”拦住。后来老老实实打开开发者工具找到余票查询和提交订单两个接口改用requests直接请求速度和稳定性都上来了。2.3 为什么我推荐“半自动”而不是“全自动”所谓全自动就是脚本连登录、验证码、滑块全部自己处理。理论上很诱人但实际写的时候你会发现票务平台的风控不是吃素的一旦检测到高频自动化行为验证码会频繁出现甚至账号被临时限制。与其花大量时间去破解这些机制不如做一套“半自动”流程脚本负责轮询、下单、异常重试遇到验证码或滑块时由人工介入处理。这种设计的好处有两个。第一开发成本低很多我只需要关心核心的请求逻辑不需要和前端加密对抗。第二账号安全性高不会因为代码里某个参数写错导致被平台判定为外挂。我在实际使用中遇到验证码的概率并不高但只要出现就暂停脚本手动点一下然后再继续。整个过程也就多花十几秒但账号安全很多。3. 抢票脚本的核心结构登录、选座、下单三步走3.1 登录与Cookie管理直接通过requests模拟登录票务平台往往是件痛苦的事很多平台的登录接口有加密参数单纯用账号密码很难构造出合法请求。我自己的做法是先打开浏览器手动完成一次登录然后从开发者工具里复制Cookie放到脚本里作为请求头。这样既绕开了复杂的登录加密又保证了身份信息的真实性。这里要特别注意Cookie是有时效的不同平台有效期不一样短的可能只有几小时长的能维持几天。所以脚本里应该保留一份读取Cookie的代码每次运行前手动检查一下是否过期。简单示例import requests COOKIES { sessionid: 你的sessionid, user_token: 你的user_token, } HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Referer: https://example.com/concert/123, }复制Cookie时建议把请求头里的User-Agent一起复制很多风控系统会同时校验这两者。如果发现请求返回“未登录”或“请先登录”第一件事就是检查Cookie有没有过期而不是怀疑代码写错。3.2 抢票主流程开票前倒计时与快速下单主流程我写成了一个死循环开票前每0.5秒查一次余票发现有余票就跳出循环去执行下单函数。轮询频率不建议太快低于0.3秒的请求率很容易触发接口限流反而适得其反。下面是一个简化版本的余票检查逻辑import time def check_ticket(): url https://api.example.com/concert/ticket/status resp requests.get(url, cookiesCOOKIES, headersHEADERS, timeout3) data resp.json() return data.get(has_ticket, False) while True: try: if check_ticket(): print(检测到余票开始下单) break except Exception as e: print(请求异常等待重试, e) time.sleep(0.5)真正跑起来之后你会发现最耗时的不是判断逻辑而是网络请求本身。如果余票接口的响应时间超过1秒0.5秒的循环就名存实亡。所以我在代码里把timeout设置为3秒同时对异常做了捕获保证单个请求失败不会让整个脚本退出。3.3 订单提交接口的正确调用姿势检测到余票后下一步是提交订单。这一步比轮询余票更容易出错因为提交订单通常需要携带更多参数场次ID、票档ID、观演人ID以及用于防伪的token字段。我在调试时踩过最典型的坑就是少带了一个动态token导致接口直接返回“参数错误”。正确做法是先在浏览器里手动完成一次下单流程在开发者工具里找到提交订单的POST请求把请求体里的字段逐个和页面上的选择对应起来。比如场次对应页面上的日期时间票档对应“看台399/内场1299”这种按钮观演人对应你添加的购票人姓名。参数补齐后提交代码类似def submit_order(show_id, price_id, viewer_ids): url https://api.example.com/order/create payload { show_id: show_id, price_id: price_id, viewer_ids: viewer_ids, token: 从请求体中复制, } resp requests.post(url, jsonpayload, cookiesCOOKIES, headersHEADERS) result resp.json() if result.get(success): print(下单成功订单号, result[order_id]) else: print(下单失败, result.get(message)) return result提交成功后不代表就结束了。很多平台在高峰期会返回“排队中”或者“库存紧张”这时候需要轮询订单状态直到确认订单真正生成再引导自己去支付。千万不要因为没立刻看到结果就重复提交否则可能出现两个重复订单处理起来非常麻烦。4. 实战中的风控与排队问题我的踩坑记录4.1 一次“订单状态未知”的排查过程我用脚本抢票的时候遇到过这么一件事提交订单接口返回了“成功”但页面订单列表里却看不到任何记录。第一次遇到时我以为是脚本出了问题反复提交了好几次结果一个订单都没生成反而把自己账号的请求频率拉高了。后来静下心来排查才发现真正的原因在于请求成功只是服务端接收了请求并不代表库存锁定成功。由于我提交订单的速度太快触发了平台内部的排队机制很多请求进入队列后又被异步丢弃了接口却返回了“已接收”的假象。那次排查的链路大致是先看接口返回码确认是不是200再看响应体里的业务状态码区分code0和code1的含义然后重新打开浏览器手动下一单对比正常订单和异常订单的请求参数差异最后发现需要在提交订单后继续轮询一个“订单确认”接口只有当确认接口返回有效订单号才代表锁单成功。从那以后我的脚本里就多了一个“确认订单”步骤宁可慢一点也不要一次次重复提交造成脏数据。4.2 验证码与滑块验证的处理原则很多人喜欢研究怎么自动通过滑块验证我劝你少走这个弯路。验证码和滑块出现的本质是风控系统已经注意到异常请求了。这时候继续加大自动化力度只会让账号的风险等级更高。我的原则很简单脚本检测到验证码元素或接口返回验证码标记时立刻暂停自动提交切换到人工处理。如果你用的是requests直连接口可以观察下单响应里是否包含类似need_captcha的字段。如果包含就说明需要人工打开浏览器完成一次验证然后拿着新的Cookie继续跑。如果你用的是selenium或playwright处理起来更直观截个图弹窗提醒让人工把滑块拖到指定位置。实测下来人工处理滑块的成功率远高于程序模拟而且账号更安全。4.3 频率控制与IP限制别因为抢票把自己账号搞封了抢票脚本最容易犯的错就是以为“请求越多越容易抢到票”。其实所有正规票务平台都有接口频率限制短时间请求次数过多轻则返回“操作频繁”重则直接封禁账号。我在调试早期就因为轮询间隔设置成0.1秒导致账号被临时限制登录差点错过了正式开票时间。后来我给自己定了几条参数底线轮询间隔不低于0.5秒提交订单后至少要等待2秒再查状态每次开票最多连续尝试10次提交超过10次就停下来休息30秒所有请求都增加随机延迟比如在基础间隔上增加0.1到0.3秒的随机数让请求节奏更接近真人操作。这些参数不保证一定能抢到票但至少能保证账号活着活着才有机会。4.4 日志和断点续跑脚本稳定性的最后一道防线脚本跑在本地最怕就是运行到一半崩溃而你刚好走开喝了个水。那次排查订单状态问题时我发现脚本在请求异常后直接死循环没有记录任何有效日志导致我完全不知道卡在哪一步。后来我加了loguru日志每次轮询、每次下单、每次异常都记录带时间戳的日志一旦出错能很快定位。同时我会把抢票的“状态”写入一个本地JSON文件比如当前是否已经下单、订单号是多少、是否已确认。如果脚本中途崩了重启后先读状态文件判断是继续轮询还是直接进入等待支付而不是傻傻地重新下单。这套“断点续跑”的设计让整个抢票过程可靠很多。5. 从抢票脚本到自动化工具合规边界与后续扩展5.1 哪些事情一定不能做写了这个项目之后经常有人问我能不能帮忙写一个“代抢工具”或者做成多开、多线程版本去提高成功率。我的答案都是拒绝。原因很简单用脚本抢票用于个人学习、节省重复操作时间这是合理的但如果你用它批量注册账号、囤票、高价倒卖或者绕过平台验证码、突破接口频率限制那就完全变了性质轻则违反用户协议重则涉及法律风险。我这里要特别强调几个不能碰的边界不要尝试破解任何验证码不要多线程并发请求去压测平台不要收集他人账号信息不要爬取非公开的接口数据。Python是个强大的工具但工具本身不分善恶使用方式却决定了风险。写这个项目时我给自己立的规矩是只在开票时段使用不恶意占用资源不用于任何商业用途。5.2 抢票脚本之外的自动化学习思路虽然抢票只是一个很小的场景但它把Python自动化的几个核心知识点串起来了HTTP请求和会话维持、Cookie与登录态、接口分析与参数构造、异常处理与重试机制、日志记录与状态管理。这些知识完全可以直接迁移到其他自动化任务上比如自动化报名、定时签到、库存监控、报表拉取等等。如果你想深入学习我建议从“把这个脚本部署到云服务器上”开始加上定时调度让它每天自动检查某场演出的余票有票时发个邮件或微信通知给自己。还可以尝试用FastAPI写一个简单的Web控制台在浏览器里手动修改目标场次和票档。你会发现抢票脚本只是自动化项目的一扇门门后才是真正的Python实战能力。5.3 我对这类效率工具的真实态度做了这个项目后我不再觉得“抢票脚本”是个神秘的东西。它的核心价值是让程序替人去等、去盯、去重试把人从机械操作里解放出来。但同时我也清楚这类工具天然带着灰色色彩因为每一个被脚本抢到的票背后可能是另一个人没抢到的遗憾。所以我在实际使用中给自己定了一个很保守的原则只抢自己真正要去的场次不一次性抢多个场次、不帮人代抢、不囤票占坑。我最后分享一个自己的小技巧与其把整个流程都交给脚本不如把它当成一个“加速器”。开票前我还是会在电脑前守着脚本一旦检测到余票立刻给我弹窗提醒我再手动确认场次和票价。这样既保证了速度也留了一道人工判断的阀门很多因为参数错误导致的烂摊子其实都能靠这一道阀门拦下来。希望这篇复盘能给你一些启发也祝你下次开票时能顺利见到想见的人。本文还有配套的精品资源点击获取