文章目录
- 前言
- 一、分析购票过程
- 二、Selenium 模拟浏览器操作
- 三、逆向工程:抢票接口
- 总结
前言
你是否错过了周杰伦的票,最近又没抢到五月天的票,不要太难过,今晚有张学友的票,后天还有张杰的票,加油哦!
为了帮助你在激烈的抢票竞争中获得更大的成功机会,本文将介绍抢票软件的实现原理以及我所了解的一些抢票方式。但是,请不要过度将希望寄托于抢票软件,它有时也不灵,经过我的验证,即使你用到了抢票软件,也不一定能抢到票。
票务平台会经常调整反爬策略打击爬虫行为,如果希望抢票软件保持较高的成功率,是需要开发者针对票务平台的打击策略作出逻辑调整,这个成本是很高的,所以你能随手获得的抢票软件很大概率是抢不到票的或者说是不安全的。
在调研过程发现一个有意思的点 “黄牛的票从来不是抢来的”。相关规定,面向市场公开销售的营业性演出门票数量,不得低于核准观众数量的70%。 而剩下的那 30%,即非公开销售的票,则是黄牛票的主要来源,也叫渠道票。这里面涉及主办方对热门票和冷门票的售票策略,黄牛在这链条中扮演着重要的角色,只要演唱会门票的二级市场不会消失,黄牛就永远不会消失,对于市场本身来说,愿意花更多钱买黄牛票的人,一定是更有需求的人,黄牛不过是市场调节的人格化。
一、分析购票过程
现在无论是买火车票、飞机票、演唱会票基本都是使用电子支付网上购票,之后得到一张电子票凭证,进场前打印纸质票或者闸机核销票据二维码进场,那么我们从用户角度看下,一次完整的购票过程是什么样。
用户的购票流程:
- 首先用户登录 票务 APP 搜索爱豆的门票,点击查看门票详情,然后选择场次和票档。等待抢票倒计时,才能进入到下一个页面;
- 倒计时结束后,开抢按钮被点亮,用户进入下一步选择观演人,确认信息后选择付款方式提交订单;
- 如果手速足够快、运气足够好,抢到了票就会唤起所选的支付方式 APP 提示付款;如果没有抢到则会提示拥堵,跳转到票档选择页面。
下面,我将这个图补充一下,思考下哪些步骤是用户可以提高出票成功率的关键时间节点:
很显然,用户在倒计时之前看不到的页面就是竞争手速的关键时机,当这个开抢按钮被倒计时点亮的一瞬间,要以最快的速度点击到达隐藏页面,然后选中观演人,通常使用默认的支付方式,最后提交订单。一旦订单被提交成功,就说明锁定了席位抢到了票。如果用户在规定的时间内未付款,该席位会重新流入票池,捡漏的人就可以抢到。
到这里,我们知道了购票流程和提高抢票成功率的突破口,人的手速肯定没有机器快,接下来介绍下两种常用的技术抢票方案。
二、Selenium 模拟浏览器操作
在使用 Chrome 浏览器,用户可以使用鼠标滑动、按键点击以及键盘输入,作为信号输入设备向浏览器传达指令,浏览器收到指令后执行渲染。
这里提到的 Selenium WebDriver 是对浏览器提供的原生 API 进行封装,使用这套 API 可以操控浏览器的开启、关闭,打开网页,操作界面元素,控制 Cookie。简单说就是,可以通过写代码的方式来自动实现用户鼠标和键盘信号的输入。这么一来,可以做的事就非常多了。
下面是一个简单脚本,它首先打开 chrome 浏览器输入 google 的网址,等待 5 秒,浏览器网页打开后,找到输入框输入 ”ChromeDriver“,然后模拟点击搜索按钮,就能看到浏览器上搜索的结果。
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
browser.get("https://www.google.com")
time.sleep(5)
# 查找元素
search_box = browser.find_element(By.NAME, 'q')
# 模拟按键输入
search_box.send_keys('ChromeDriver')
# 搜索框模拟回车
search_box.submit()
time.sleep(5)
# 关闭所有窗口
browser.quit()
回到抢票的主题上来,我们可以使用这种技术能力,写一个 Python 脚本,在本地机器上执行起来。脚本内容是在指定的时间打开浏览器,打开票务网页,然后自动模拟用户选择观影人然后自动提交订单。(在这里我原本很想做一个演示视频,理解起来更直观,奈何时间精力有限,这里就不详细介绍 Selenium WebDriver 开发环境配置,感兴趣的可以继续深挖。)
三、逆向工程:抢票接口
什么是逆向?即通过技术手段对票务 APP 的通讯流量抓包,定位 获取票档、提交订单的关键请求解密 https 流量,然后分析解密流量数据。
我们继续回到这张图,仔细观察会发现,用户查看门票详情以及选择票档等一些动作都是 APP 上完成的都是提前加载好的,而真正决定用户抢票的是 “提交订单” 这个关键请求。如果我们可以将这个这个请求的流量抓到,然后分析其参数构造规则,就可以编写程序自动发送请求了。
下面抓包示例,选取了一个门票,抓包获取了其票档信息。
以此类推,抓包 下单接口 观察其参数构成,编写程序模拟用户请求。
# 等待开售
def wait_for_buy():
# 抢购时间
start_timestamp = 1686475533
# 当前时间
current_timestamp = int(time.time())
while current_timestamp > start_timestamp:
# 开始购买
place_order()
这里简要介绍了下实现思路和方向,不展开逆向过程的细节。具体实现没有这么简单的,有攻击方必然有防守方,票务方为了保障平台方利益,势必会定义打击策略,例如,我们会看到验证码从文字到图片再到滑块验证的一个迭代过程。技术方面是一个问题,法律方面也是一个问题,所以全当一次攻防演练的学习,不要伤害票务方的利益。
总结
生活有时很操蛋,我们会感到力不从心,但请守住你的热爱,别让它被挫折磨灭”。祝大家买票的时候都能以正常价格抢到自己心仪的演唱会门票 ~