马后炮之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的下载,十分抱歉。

转载于:https://www.cnblogs.com/comsokey/p/Train1230642014.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为虚拟一键部署服务器,一键部署云服务器

一键部署云服务器 内容精选换一换SAP NetWeaver分布式部署如图1所示。该部署方式是由多个SAP实例组成&#xff0c;一个SAP实例是一组同时开始和结束的进程。在分布式系统中&#xff0c;所有实例都运行在独立的云服务器上&#xff0c;主要包括以下实例&#xff1a;ABAP Central …

ADO.NET多值查询

1,新控件,可以显示很多数据,视觉清晰.相当于表. listView,列表视图 添加与数据库相关的列名. SqlDataReader sdr cmd.ExecuteReader(); listView.Items.Clear();//避免数据重复 while(sdr.Read())//读所有行 {string a sdr["第一个列名"].ToString();ListviewIte…

1040. 有几个PAT(25

字符串APPAPT中包含了两个单词“PAT”&#xff0c;其中第一个PAT是第2位(P),第4位(A),第6位(T)&#xff1b;第二个PAT是第3位(P),第4位(A),第6位(T)。现给定字符串&#xff0c;问一共可以形成多少个PAT&#xff1f;输入格式&#xff1a;输入只有一行&#xff0c;包含一个字符串…

前端学习(971):swiper插件使用

引入 2复制div部分 不要修改里面的文件 3复制css样式 4复制js 注意winows.addEventListener 加载后使用 5运行结果

1051. 复数乘法 (15)

复数可以写成(A Bi)的常规形式&#xff0c;其中A是实部&#xff0c;B是虚部&#xff0c;i是虚数单位&#xff0c;满足i2 -1&#xff1b;也可以写成极坐标下的指数形式(R*e(Pi))&#xff0c;其中R是复数模&#xff0c;P是辐角&#xff0c;i是虚数单位&#xff0c;其等价于三角…

ios企业应用发布流程

转载自:http://blog.csdn.net/justinjing0612/article/details/8758692留作备忘 企业发布app的 过程比app store 发布的简单多了&#xff0c;没那么多的要求&#xff0c;哈 但是整个工程的要求还是一样&#xff0c;比如各种像素的icon啊 命名规范啊等等。 下面是具体的流程 1、…

前端学习(975):bootstrap轮播图

1引入js和css 2引入html 2运行结果

linux3.0.4编译LDD中的scull全过程

按照惯例&#xff0c;我是应该先写一些本章的收获的&#xff0c;不过太晚了。 在看完第三章之后开始编译&#xff0c;错误一堆&#xff0c;几乎崩溃&#xff0c;幸亏经过不断的百度&#xff0c;总算解决了问题&#xff0c;我发现 我遇到问题比较多&#xff0c;算是集中七个龙珠…

前端学习(976):阿里百秀轮播图制作

引入js和css 复制html结构 结构调整

SAP RFC user 最小权限

今天作了几个rfc供外围系统调用&#xff0c;他们使用.net。 在.net调用时&#xff0c;提示“Lookup of function ET_PRDATA metadata failed for destination ZNMMPT_EXPORT_PR”。 这个错误&#xff0c;是由于GetFunctionMetadata()函数引起的&#xff0c;对此&#xff0c;NC0…

增强中获取屏幕值的一句很实用代码…

增强中获取屏幕值的一句很实用代码&#xff0c;直接获取屏幕字段值&#xff0c; 一般是在增强中用比如MIGO收货时&#xff0c;希望获取收货对应的A01这个值增强&#xff1a;BADI&#xff1a; MB_DOCUMENT_BADI MB_DOCUMENT_BADI 是在过账后了&#xff0c;不能报E类型消息&…

centOS7安装matlab2014a

1&#xff0c;网上下载matlab 2014a for linux; 2&#xff0c;挂载matlab_unix_2014a.iso到/mnt/matlab&#xff1b; mkdir /mnt/matlab2014a/ mount matlab_unix_2014a.iso /mnt/matlab2014a/ -o loop 3&#xff0c; cd /mnt/matlab2014a ./install4&#xff0c;选择第二个…

xdoj机器人ac

xdoj机器人100分 #include<stdio.h> int main() { char a[22][22]; int b[22][22]{0}; int h,l,f; scanf("%d%d%d",&h,&l,&f); getchar(); int i,j,c0; int flag0; for(i1;i<h;i) { for(j1;j<l;j) { a[i][j]getchar(); }getchar();} for(i1;…

最大子段和c(c语言实现)

1&#xff0c;题目 2&#xff0c;各种算法 暴力解决&#xff0c;就是所有的情况都遍历一遍&#xff0c;然后说&#xff0c;我找到最牛逼的啦 int MaxSubseqSum1(int A[], int N, int* pidxStart, int* pidxEnd) { int sum A[0], tempSum 0;int i, j, k;*pidxStart 0, *pid…