12306抢票的关键拼的就是整点出票的速度,快的几秒钟,慢的几分钟,本文提供终极抢票攻略,通过多线程扫描上万个CDN,来大幅度提升出票速度。
准备一:需要了解CDN和切站的机制,请参考:
- 分享12306秒票杀手锏源码:http://www.cnblogs.com/guozili/p/3512490.html
- 分享12306抢票心得最终篇:http://www.cnblogs.com/guozili/p/4166675.html
准备二:需要熟悉12306最重要的查询接口和下单接口及传入的参数规范
- /otn/leftTicket/queryX 和 /otn/leftTicket/submitOrderRequest
- 具体流程请参考:解析12306订票流程
12306 CDN研究机制一
- 12306对kyfw.12306.cn用到了全站CDN缓存,至少上万的CDN IP
- 对于90%的子页面使用了CDN缓存
- 部分动态内容如个人中心,CDN将充当代理去12306实际服务器读写数据,请百度“cdn回源”
12306 CDN研究机制二
- 官方网站的自动查询,每次都会命中同一台CDN
- 拿到的都是CDN缓存数据,缓存时间2分钟
- 所以运气好的话,整点放票较快就能刷出票,一般情况下要等几十秒才能看到出票
- 参考下图:
12306 CDN研究机制三
- 360抢票王每次查询使用不同的CDN,通过内置dll插件实现,每次查询映射不同的IP
- 参考下图:
12306 频繁刷票容易被踢的猜测
- 每次查询,都会AJAX Log一下,请参考上面截图
- 如果登录状态下,cookie的token就被记录上传了
- 所以登录状态下刷票容易被踢
- 所以查询时动态修改hosts,切CDN,切站点,也容易被踢
12306 关于secretStr
- 查询返回的每个车次结果,都会有个secretStr
- 加密了此车次的所有相关信息,后续用于提交订单用
- 此secretStr几分钟后会过期
- 所以关键就是放票整点后能快速刷出这个secretStr
- 参考下图:
-
12306 查询设计思路
- 启用匿名查询,查询结果后返回的secretStr,交给登录的帐号做订单提交
- 目前市面上的抢票神器或收费软件,都是采用了此机制:
- 启用多个线程,主线程帐号登录;
- 其他线程并发匿名作业:轮询请求不同的CDN查询票源;
- 查到有票的secretStr,塞给主线程进行订单提交;
- 集成收费打码API,自动化点触验证码,实现多开无人值守抢票
终极设计思路:
- 做Winform及界面工作量太大,这里提供简单的定制方案和一些设计思路
- 服务端:自己建个本地的IIS Web站点,去匿名轮询请求不同的CDN查询票源,返回secretStr
- 客户端:浏览器登录状态,12306任何一个页面,控制台或插件植入js脚本,AJAX长轮询去请求服务端,请求到secretStr做订单提交
终极设计思路之服务端:
- 自己建个本地的IIS Web站点或在公网上建,或商业化做云服务器分布式的查询
- 此网站提供接口如:http://127.0.0.1/GetSecretStr...
- 此接口的实现:启动多线程去上万个CDN去查询指定车次日期的票源
- 查到secretStr,马上返回给客户端
帮助:获取kyfw.12306.cn的CDN ip,可以去chinaz上去获取,大概有上千个
帮助:实在不够,我能提供fishlee的一个IP列表,有上万个
终极设计思路之服务端的关键技术:
- http://www.cnblogs.com/dudu/archive/2012/07/18/webrequest_dns.html
- 这个技术,不用修改hosts,使用WebRequest能映射不同的IP
- 参考下图:
-
终极设计思路之客户端:
- 浏览器登录状态,控制台或插件植入js脚本
- AJAX长轮询去请求服务端,请求到secretStr做订单提交
- 到最后的订单提交页,用插件自动勾选人,座位,自己手动输入验证码提交
- 参考下图:
-
测试结果:整点出票秒数,根据自己以前的N次经验
- 3-10秒:此文思路,多线程在10秒内对1万个CDN进行查询
- 5-20秒:某收费软件,采用了后台多线程查询CDN
- 10-30秒:fishlee的NET订票助手,单线程,每隔1秒尝试不同CDN
- 15-60秒:360抢票王,也是单线程,但CDN数量不够
- 20-120秒:官方网站,CDN一般1分钟内不会变,缓存严重
最新更新!
- 验证码问题 参考:http://bbs.fishlee.net/thread-10058-1-1.html
- 现在没时间研究 工具 加入验证码输入功能,
- 工具源代码在:https://github.com/guozili/12306
- 基本思路可以实现下: console工具 要输入验证码时,发送验证码图片二进制(socket)到 verifycodeWPFInput.exe(实现一个WPF程序弹出来)去点击,然后返回验证码坐标给console