Python 大麦网抢票脚本全解析:从原理到实战
介绍基于 Python+Selenium 的大麦网抢票脚本,采用面向对象与模块化设计。核心功能包括 Cookie 免登录、自动选座监控及订单提交。文章详细拆解了基础配置、核心类 Concert、各功能模块(Cookie 管理、登录、抢票、辅助工具)及入口函数逻辑。实战部分涵盖依赖安装、Chrome 驱动配置及优化建议,如使用显式等待替代固定延时。脚本旨在模拟人工操作以提升效率,但无法突破平台防爬机制。

介绍基于 Python+Selenium 的大麦网抢票脚本,采用面向对象与模块化设计。核心功能包括 Cookie 免登录、自动选座监控及订单提交。文章详细拆解了基础配置、核心类 Concert、各功能模块(Cookie 管理、登录、抢票、辅助工具)及入口函数逻辑。实战部分涵盖依赖安装、Chrome 驱动配置及优化建议,如使用显式等待替代固定延时。脚本旨在模拟人工操作以提升效率,但无法突破平台防爬机制。

在抢票场景中,手动操作往往难以匹敌抢票工具的响应速度。今天分享一款基于 Python+Selenium 的大麦网抢票脚本,它通过面向对象编程思想,将复杂抢票流程拆分为独立模块,实现了 Cookie 免登录、自动选座、订单提交等核心功能。本文将从模块设计、核心原理、实战注意事项三个维度,带你吃透这款脚本的每一处细节。
脚本整体采用「面向对象 + 模块化」设计,核心逻辑封装在 Concert 类中,配合全局配置模块和入口函数,形成'配置→初始化→登录→抢票→收尾'的完整流程。
整体结构图谱:
大麦网抢票脚本 ├── 基础配置模块(库导入 + 全局常量) ├── 核心类 Concert(抢票主逻辑) │ ├── Cookie 管理模块(免登录核心) │ ├── 登录模块(登录方式分发 + 页面初始化) │ ├── 抢票核心模块(选座 + 下单) │ └── 辅助工具模块(元素判断 + 资源释放) └── 入口函数(脚本执行入口)
这种设计的优势在于:单个模块职责单一,便于维护和扩展(比如更换演出、修改登录方式时,仅需调整对应模块)。
基础配置模块负责准备脚本运行所需的依赖库和固定参数,是整个脚本的'起点'。
import os # 文件存在性判断、路径处理
import time # 延时控制,模拟人工操作节奏
import pickle # Cookie 序列化/反序列化,实现免登录
from time import sleep # 简化延时调用
from selenium import webdriver # 浏览器自动化核心工具
from selenium.webdriver.common.by import By # 元素定位方式枚举
各库的核心作用的:
selenium:核心依赖,负责打开浏览器、定位按钮、模拟点击等所有交互操作;pickle:解决'重复登录'问题,将登录后的 Cookie 保存到本地,下次运行直接复用;os:判断 Cookie 文件是否存在,实现'有 Cookie 免登录,无 Cookie 则手动登录'的逻辑;time/sleep:避免操作过快导致页面未加载完成,平衡'抢票速度'和'操作稳定性'。# 大麦网核心页面 URL
damai_url = 'https://www.damai.cn/'
login_url = 'https://passport.damai.cn/login?ru=https%3A%2F%2Fwww.damai.cn%2F'
target_url = '目标演出详情页' # 需抢票的演出页面
常量设计的意义:将高频使用的 URL 固化,后续更换演出时,仅需修改 target_url,无需改动核心逻辑,降低维护成本。
Concert 类是脚本的核心,所有抢票操作都围绕这个类的方法展开。类内通过属性控制流程状态,通过方法实现具体功能,逻辑清晰且可复用。
def __init__(self):
self.status = 0 # 流程状态标记(0=初始化,2=登录成功,3/4/5=不同购票阶段)
self.login_method = 1 # 登录方式(0=模拟登录,1=Cookie 免登录)
self.driver = webdriver.Chrome(executable_path='chromedriver.exe') # Chrome 驱动对象
self.status:相当于'流程进度条',通过状态值控制后续操作(比如只有 status=2(登录成功),才能执行选座操作);self.login_method:支持两种登录方式切换,Cookie 免登录是核心优化点,避免重复扫码 / 输入账号密码;self.driver:Chrome 浏览器驱动实例,所有浏览器操作(打开页面、点击按钮等)都通过该对象实现。Cookie 是网站记录用户登录状态的关键数据,该模块通过'保存 Cookie→读取 Cookie'的流程,实现免登录功能,是抢票效率的核心保障。
set_cookies():首次登录并保存 Cookiedef set_cookies(self):
self.driver.get(damai_url) # 打开大麦主页
print('###请点击登录###') # 等待用户点击登录按钮(页面标题未变则持续等待)
while self.driver.title.find('大麦网 - 全球演出赛事官方购票平台') != -1:
sleep(1)
print('###请扫码登录###') # 等待用户扫码完成(登录成功后页面标题变化)
while self.driver.title != '大麦网 - 全球演出赛事官方购票平台 -100% 正品、先付先抢、在线选座!':
sleep(1)
# 保存 Cookie 到本地文件
pickle.dump(self.driver.get_cookies(), open('cookies.pkl', 'wb'))
print('###cookie 保存成功###')
self.driver.get(target_url) # 跳转到抢票页
核心逻辑:
pickle.dump() 将 Cookie 写入 cookies.pkl 文件,实现状态持久化。get_cookie():读取 Cookie 实现免登录def get_cookie(self):
# 读取本地 Cookie 文件
cookies = pickle.load(open('cookies.pkl', 'rb'))
for cookie in cookies:
# 构造符合要求的 Cookie 字典(必须指定 domain,否则无效)
cookie_dict = {
'domain': '.damai.cn', # 关键:Cookie 绑定的域名
'name': cookie.get('name'),
'value': cookie.get('value')
}
self.driver.add_cookie(cookie_dict) # 注入 Cookie 到浏览器
print('###载入 cookie###')
关键注意点:
domain: '.damai.cn' 是必填项:Cookie 是域名绑定的,不指定域名会导致 Cookie 注入无效,无法免登录;target_url),再注入 Cookie,否则 Cookie 无法生效。登录模块负责根据配置的登录方式,完成'手动登录'或'Cookie 免登录',并初始化抢票页面。
login():登录方式分发def login(self):
if self.login_method == 0:
self.driver.get(login_url) # 直接打开登录页,手动登录
print('###开始登录###')
elif self.login_method == 1:
# 检查 Cookie 文件是否存在
if not os.path.exists('cookies.pkl'):
self.set_cookies() # 无 Cookie 则执行首次登录并保存
else:
self.driver.get(target_url) # 有 Cookie 则直接打开抢票页
self.get_cookie() # 注入 Cookie 免登录
逻辑分支:
enter_concert():初始化浏览器 + 登录 + 弹窗处理def enter_concert(self):
print('###打开浏览器,进入大麦网###')
self.login() # 执行登录
self.driver.refresh() # 刷新页面,使 Cookie 生效
self.status = 2 # 标记登录成功
print('###登录成功###')
# 关闭登录后的弹窗(通过 XPATH 定位关闭按钮)
if self.isElementExist('/html/body/div[2]/div[2]/div/div/div[3]/div[2]'):
self.driver.find_element(By.XPATH, '/html/body/div[2]/div[2]/div/div/div[3]/div[2]').click()
额外处理:
isElementExist() 判断并关闭,避免弹窗遮挡后续操作。这是脚本的核心业务模块,负责监控购票按钮状态、自动选座、提交订单,全程模拟人工抢票流程。
choose_ticket():监控购票按钮并触发对应操作def choose_ticket(self):
if self.status == 2: # 仅登录成功后执行
print('=' * 30)
print('###开始进行日期及票价选择###')
# 未进入订单页面则持续监控
while self.driver.title.find("确认订单") == -1:
try:
buybutton = self.driver.find_element(By.CLASS_NAME, 'buybtn').text # 根据按钮文本执行不同操作
if buybutton == '提交缺货登记': # 无票状态,刷新页面重新监控
self.driver.get(target_url)
elif buybutton == '立即预定':
self.driver.find_element(By.CLASS_NAME, 'buybtn').click()
self.status = 3
elif buybutton == '立即购买':
self.driver.find_element(By.CLASS_NAME, 'buybtn').click()
self.status = 4
elif buybutton == '选座购买':
self.driver.find_element(By.CLASS_NAME, 'buybtn').click()
self.status = 5
except:
print('###没有跳转到订单结算界面###')
# 分支处理:选座购买/确认订单
if self.driver.title == '选座购买':
self.choice_seats() # 选座逻辑
elif self.driver.title == '确认订单':
# 提交订单逻辑
while True:
if self.isElementExist('//*[@id="container"]/div/div[9]/button'):
self.check_order()
break
核心逻辑:
choice_seats():选座购买逻辑def choice_seats(self):
# 停留在选座页面时持续处理
while self.driver.title == '选座购买':
# 等待用户选座(提示用户手动选座)
while self.isElementExist('//*[@id="app"]/div[2]/div[2]/div[1]/div[2]/img'):
print('请快速选择你想要的座位!!!')
# 选座完成后点击确认按钮
while self.isElementExist('//*[@id="app"]/div[2]/div[2]/div[2]/div'):
self.driver.find_element(By.XPATH, '//*[@id="app"]/div[2]/div[2]/div[2]/button').click()
注意:脚本不支持自动选座(大麦网选座需要人工点击座位区域),此处仅在用户选座后,自动点击'确认选座'按钮。
check_order():提交订单逻辑def check_order(self):
if self.status in [3, 4, 5]:
print('###开始确认订单###')
time.sleep(1) # 等待页面加载
try:
# 选中第一个购票人(需提前在大麦网添加购票人信息)
self.driver.find_element(By.XPATH, '//*[@id="container"]/div/div[2]/div[2]/div[1]/div/label').click()
except Exception as e:
print('###购票人信息选中失败,自行查看元素位置###')
print(e)
# 提交订单(延时 0.5 秒避免点击无效)
time.sleep(0.5)
self.driver.find_element(By.XPATH, '//*[@id="container"]/div/div[9]/button').click()
time.sleep(20) # 预留支付时间
关键细节:
该模块提供通用工具方法,支撑核心模块的稳定运行。
isElementExist():判断元素是否存在def isElementExist(self, element):
flag = True
try:
self.driver.find_element(By.XPATH, element) # 尝试定位元素
return flag
except:
flag = False
return flag
作用:避免因元素未加载(如按钮、弹窗)导致脚本报错崩溃,是脚本稳定性的重要保障(比如判断弹窗是否存在、提交订单按钮是否加载完成)。
finish():脚本收尾def finish(self):
self.driver.quit() # 关闭浏览器,释放资源
作用:抢票完成或出现异常时,关闭浏览器,避免占用系统资源。
if __name__ == '__main__':
con = Concert() # 实例化抢票类
try:
con.enter_concert() # 初始化浏览器 + 登录
con.choose_ticket() # 开始抢票
except Exception as e:
print(e) # 打印异常信息
con.finish() # 异常时关闭浏览器
执行流程:实例化 Concert 类 → 调用 enter_concert() 完成登录和页面初始化 → 调用 choose_ticket() 开始抢票 → 捕获异常并关闭浏览器,确保脚本优雅退出。
pip install selenium 安装核心库;chromedriver.exe 版本与本地 Chrome 浏览器版本一致(或改用 webdriver_manager 自动适配);cookies.pkl 文件后重新运行脚本,手动登录更新 Cookie。logging 模块,记录抢票流程和异常信息,便于排查问题;ddddocr 等 OCR 库自动识别滑动缺口(需额外开发)。显式等待替代固定延时:用 WebDriverWait 替代 sleep(),减少无效等待,提升抢票速度:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 示例:等待购票按钮加载完成(最多等待 10 秒)
WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'buybtn')))
这款大麦网抢票脚本的核心优势在于'模块化设计'和'Cookie 免登录',将复杂的抢票流程拆分为独立模块,既便于理解和维护,又能灵活扩展功能。脚本本质是'模拟人工操作',无法突破大麦网的防爬机制(如验证码、排队机制),但能通过自动化减少人工操作的延迟,提升抢票成功率

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online