马后炮之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 你好,我是测试蔡坨坨. 随着行业内卷越来越严重,自动化测试已成为测试工程师的必备技能,谈及自动化测 ...
随机推荐
- [转载]C#中as和is关键字的用法
这篇文章主要介绍了C#中as和is关键字的用法的相关资料,需要的朋友可以参考下. 原文链接:http://www.jb51.net/article/80944.htm#comments 在程序中,进 ...
- java入门笔记(1)
上图表达的是我们写的java程序是怎么在电脑上运行并算出结果的.编译器判断语法是否正确,如果错误,不能生成.class文件. JVM(Java Virtual Machine)是java虚拟机. JV ...
- javascript创建对象的几种模式
在js中有几种模式可以创建对象,通过对象操作所包含的属性与方法. 一般来说,构造函数名称的第一个字母为大写字母,非构造函数名称的第一个字母为小写字母,当然,构造函数与一般函数唯一的区别只是调用的方式不 ...
- JavaScript时间处理之几个月前或几个月后的指定日期
在平常项目开发过程中,经常会遇到需要在JavaScript中处理时间的情况,无非两种(1,逻辑处理 2,格式转换处理).当然要说相关技术博,园子里闭着眼睛都能抓一把,但是我要做的是:既然有幸被我碰到 ...
- jQuery - 全国省市县三级联动
最近有空用jquery做了一个全国省市县的三级联动,在以后或许可以用的到 ,遗憾的是我还没用封装,等有空看能不能封装成一个插件 废话不多说,贴上代码: <!doctype html> &l ...
- HTML DOM 教程
HTML DOM DOM 教程 DOM 简介 DOM 节点 DOM 方法 DOM 属性 DOM 访问 DOM 修改 DOM 内容 DOM 元素 DOM 事件 DOM 导航 一,HTML DOM 简介 ...
- SharePoint 2013 入门教程之入门手册
当我们搭建完环境,创建应用程序和网站集后,就已经正式开启了我们的SharePoint之旅了,进入网站以后,开始基本的使用.设置,了解SharePoint相关特性,下面,来简单了解下SharePoint ...
- Linux 通过sendmail 发邮件到外部邮箱
最近在写自动化巡检脚本,想着怎么预警后自动发送邮件报警. 首先下载最新版本mailx-12.4.tar.bz2 # wget http://sourceforge.net/projects/heirl ...
- EditText的inputType常用取值
最近经过实际试验,总结了InputType几个常用取值表示的含义: 1.none, text, textVisiblePassword: 无任何输入限制 2.textMultiLine: 允许多行输入 ...
- Symantec Backup Exec Remote Agent 2010在Redhat Enterprise 6.6上启动问题
在Red Hat Enterprise Linux Server release 6.6 (Santiago)上安装了Symantec Backup Exec Remote Agent 2010后,启 ...