马后炮之12306抢票工具(四)--抢票Demo,2014年1月9日终结版
时隔一年多,终于朋友的忽悠下吧抢票Demo的最后一步完善了,与2014年1月9日成功生成车票。
Demo仅经过自己测试,并未在高峰期进行测试,代码质量很差,因为赶工,套用去年模板并未使用设计模式。
代码存在如下BUG:
1)代码使用 。net 4.5的事件,如果使用4.0或以下的同学,请根据错误提示,更改事件即可。已上传两个版(.net4.0 .net4.5)本。
2)添加、刷新常用联系人功能缺失,按钮已屏蔽。请在官网添加后,重新登录软件即可刷新。
3)验证码为手动输入,不支持自动识别。未做原因如下:1.本人太懒了,2.验证码经常变化,防止哪天变成公式计算,中文识别等特殊情况。
时间仓促,代码整体结构是去年的,编写的代码很垃圾,未使用任何设计模式,仅从目的出发,并未考虑任何效率、兼容性、安全性、可维护性等问题。高手请绕道,勿喷,谢谢。
如过有任何问题,可以在评论中一起探讨。如对代码有问题,可以一起讨论。
本文最后放出的Demo仅供学习,请勿用于抢票操作。
什么都不说,先上图:


软件工作流程:
1)拉取登陆验证码
2)登陆,获取Cookie
3)拉取常用联系人
4)搜索车次前拉取城市地址,供给2221个城市
5)按时间获取车次信息,并供给用户选择
6)用户选择指定车次,指定日期获取车次及车票信息
7)根据用户选择座位号,比多刚拉取的车票信息。如果没有车票则间隔6秒时间后重新刷票(int m = 6 * 100;)。
8)如果有票,判断用户是否有勾选常用联系人,如果未勾选则不进行抢票
9)抢票第一步:请求https://kyfw.12306.cn/otn/confirmPassenger/autoSubmitOrderReques页面获取Token
提交车次信息:
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("secretStr", train.Id);
dic.Add("train_date", date);
dic.Add("tour_flag", "dc");
dic.Add("purpose_codes", "ADULT");
dic.Add("query_from_station_name", From.Name);
dic.Add("query_to_station_name", To.Name);
dic.Add("", "");
dic.Add("cancel_flag", "2");
dic.Add("bed_level_order_num", "000000000000000000000000000000");
dic.Add("passengerTicketStr", passengerTicketStr.ToString().TrimEnd('_'));
dic.Add("oldPassengerStr", oldPassengerStr.ToString());
Referer: "https://kyfw.12306.cn/otn/leftTicket/init"
headers: new Dictionary<string, string>() { { "Origin", "https://kyfw.12306.cn" },{"X-Requested-With", "XMLHttpRequest"} }
PostData、Cookie、Referer、Headers这几个是重点,必须要有,否则失效。
返回Json:data.data.result中保存Token,如:
Q6#BA6C4F23E49E84F96A07B8ECA37A9FF350DAD2E2F484AD96F61C2046#O007450669M0099501499019950025#1
为统一名称,规定data.data.result使用#进行切割后命名:Q#长Token#短Token#数字
10)抢票第二步:请求页面https://kyfw.12306.cn/otn/confirmPassenger/getQueueCountAsync获取车票数量
提交车次数据:
dic.Clear();
dic.Add("train_date",
(Convert.ToDateTime(date).ToString("ddd MMM dd yyy ", DateTimeFormatInfo.InvariantInfo) +
DateTime.Now.ToString("HH:mm:ss").Replace(":", "%3A") + " GMT%2B0800 (China Standard Time)").Replace(' ', '+'));
dic.Add("train_no", train.TrainNo);
dic.Add("stationTrainCode", train.StationTrainCode);
dic.Add("seatType", seatType);
dic.Add("fromStationTelecode", train.from_station_telecode);
dic.Add("toStationTelecode", train.end_station_telecode);
dic.Add("leftTicket", token.ShortToken);
dic.Add("purpose_codes", "ADULT");
dic.Add("_json_att", "");
//注:train_date可以使用URl编码即可,转码前内容:Fri Oct 10 2014 09:59:42 GMT+0800 (China Standard Time)
Referer: "https://kyfw.12306.cn/otn/leftTicket/init"
headers:
new Dictionary<string, string>()
{
{"Origin", "https://kyfw.12306.cn"},
{"X-Requested-With", "XMLHttpRequest"}
});
返回值:data.data.ticket与短Token一致
11)抢票第三步:https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew.do?module=login&rand=sjrand&拉取抢票验证码:
Get页面,仍然要带入Cookies、Referer,但无需带入headers
12)抢票第四步:请求https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueueAsys,生成车票
请求数据:
dic.Clear();
dic.Add("passengerTicketStr", System.Web.HttpUtility.UrlEncode((passengerTicketStr.ToString().TrimEnd('_'))).ToUpper());
dic.Add("oldPassengerStr", System.Web.HttpUtility.UrlEncode(oldPassengerStr.ToString()).ToUpper());
dic.Add("randCode", Code);
dic.Add("purpose_codes", "ADULT");
dic.Add("key_check_isChange", token.LongToken);
dic.Add("leftTicketStr", token.ShortToken);
dic.Add("train_location", token.Q);
dic.Add("_json_att", "");
Referer: "https://kyfw.12306.cn/otn/leftTicket/init"
headers:
new Dictionary<string, string>()
{
{"Origin", "https://kyfw.12306.cn"},
{"X-Requested-With", "XMLHttpRequest"}
});
注:passengerTicketStr、oldPassengerStr均要UrlEncode
当data.data.submitStatus返回True时,恭喜你,已经抢票成功了,等待出票。
总结思路:
抢票与官方提供的页面自动提交抢票一次,但由于省去验证提交的验证码是否正确环节,固加快抢票速度。
扩展思路:
可以使用将抢票端分离,部署至多台计算机上,并且开启多线程。
验证码统一传输至服务器端。
再有验证码客户端去服务端拉取验证码后,由人工输入结果并返回。
可以加快抢票速度。
Demo .Net4.5 下载
Demo .New4.0 下载
Demo仅供学习,请勿用于抢票操作。
很遗憾,由于部分原因,停止提供Demo的下载,十分抱歉。
马后炮之12306抢票工具(四)--抢票Demo,2014年1月9日终结版的更多相关文章
- 微信小程序导航:官方工具+精品教程+DEMO集合(1月7更新)
1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=14764346784612:简易教程:https://mp.weixin.qq.com/debug ...
- JS对象 返回/设置年份方法 get/setFullYear() 返回/设置年份,用四位数表示。.顺序格式依次为:星期、月、日、年、时、分、秒、时区。(火狐浏览器)
返回/设置年份方法 get/setFullYear() 返回/设置年份,用四位数表示. var mydate=new Date();//当前时间2014年3月6日 document.write(myd ...
- 12306GT多线程、分流免费抢票工具使用心德
大事记背景 我相信很多远游他乡的朋友每逢佳节都会遇到一个难题,就是购票难,这个难题有多难呢?经常在12306官网购票的小伙伴应该知道每个地方的放票时间是不一样的,但是逢年过节的那几天即使你在放票几分钟 ...
- [原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(四) -- 安装crowd 3.1.2
[原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(四) -- 安装crowd 3.1.2 本来已经安装完毕, 并使用Jira集成的OAuth账户管理, ...
- [原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(四) -- 安装bitbucket 5.7.0
[原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(四) -- 安装bitbucket 5.7.0 安装Bitbucket的教程, 网上能找见的不多, ...
- Python实现C代码统计工具(四)
目录 Python实现C代码统计工具(四) 标签: Python 计时 持久化 声明 运行测试环境 一. 自定义计时函数 1.1 整个程序计时 1.2 代码片段计时 1.3 单条语句计时 二. 性能优 ...
- Appium移动自动化测试(四)--one demo(转)
Appium移动自动化测试(四)--one demo 2015-06-15 20:41 by 虫师, 40514 阅读, 34 评论, 收藏, 编辑 继续更新. ------------------- ...
- Oracle性能图表工具:awrcrt.sql 介绍,更新到了2.14 (2018年3月31日更新)
2018-03-31 awrcrt更新到了2.14版本, 下载地址为 https://pan.baidu.com/s/1IlYVrBJuZWwOljomVfta5g https://pan.baidu ...
- JetBrains新产品Aqua——自动化测试开发工具(抢鲜体验)
转载请注明出处️ 作者:测试蔡坨坨 原文链接:caituotuo.top/9a093c88.html 你好,我是测试蔡坨坨. 随着行业内卷越来越严重,自动化测试已成为测试工程师的必备技能,谈及自动化测 ...
随机推荐
- JavaScript事件对象与事件处理程序
在学习之前建议请看一下事件流.事件冒泡.事件捕获 一.事件对象 事件对象:在DOM触发事件时,会产生一个事件对象event,这个事件对象包含着所有与事件相关的信息.既然event是事件对象,那么它必然 ...
- arcgis server之路网服务发布
路网服务发布首先需要建立好道路的网络集,为了保证道路网络分析的准确性,建立网络集之前,要对道路图层进行拓扑差错,确保道路的连通性.具体操作流程为:道路拓扑差错-建立几何网络集-路网服务发布. 1.道路 ...
- 时空地图 TimeGIS.com 中生成等值线
在我的地图软件TimeGIS中加入了等值线生成的功能: 等值线的生成使用了wCoutour库, 代码根据这里的例子修改,http://www.06climate.com/view/1244.html ...
- jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解
jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解 jQuery中操纵元素属性的方法: attr(): 读或者写匹配元素的属性值. removeAttr(): 从匹配的 ...
- Android自定义ViewGroup,实现自动换行
学习<Android开发艺术探索>中自定义ViewGroup章节 自定义ViewGroup总结的知识点 一.自定义ViewGroup中,onMeasure理解 onMeasure(int ...
- IOS开发之Bug--使用xib的自动布局和代码中修改遇到的bug
首先,在xib中约束了宽高22,但是需要代码动态重设,所以一开始如下设置,但是实际显示的仍然是22,而不是重设的值: 然后直接拿xib的将布局约束对象拖线重新通过代码重设约束值,虽然打印的结果宽高值是 ...
- There is insufficient system memory to run this query 错误
服务器环境大致情况如下: 操作系统: Microsoft Windows Server 2003 R2 Enterprise Edition Service Pack 2 数据库 : Mic ...
- 【转】深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
[原文]:http://www.jb51.net/article/39432.htm 1.内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符).包括相等联接和自然联接. ...
- jQuery 3.0的buildFragment
在 jQuery3.0中,buildFragment 是一个私有函数,用来构建一个包含子节点 fragment 对象.这个 fragment 在 DOM1 中就已经有了,所有浏览器都支持.当频繁操作( ...
- JS魔法堂:ES6新特性——GeneratorFunction介绍
一.前言 第一次看koajs的示例时,发现该语句 function *(next){...............} ,这是啥啊?于是搜索一下,原来这是就是ES6的新特性Generator ...