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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM