程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 編程樂趣:C#實現讀取12306余票信息

編程樂趣:C#實現讀取12306余票信息

編輯:關於C語言

C#實現的讀取12306余票信息的,不需登錄,直接使用Get方式的字符串請求即可。

原文鏈接——本人CSDN博客


讀取余票也是用同樣的方式 讀取票價信息

也就是讀取該頁面:

204116807.jpg

使用IE9捕獲查詢時的參數:

204149905.jpg

因為這個查詢是GET方式所以直接能看到查詢的url,如下:

http://dynamic.12306.cn/otsquery/query/queryRemanentTicketAction.do?method=queryLeftTicket&orderRequest.train_date=2013-11-25&orderRequest.from_station_telecode=GZQ&orderRequest.to_station_telecode=XAY&orderRequest.train_no=&trainPassType=QB&trainClass=QB%23D%23Z%23T%23K%23QT%23&includeStudent=00&seatTypeAndNum=&orderRequest.start_time_str=00%3A00--24%3A00

這裡有四個關鍵參數:

orderRequest.train_date=2013-11-25,指需要查詢的乘車日期。

orderRequest.from_station_telecode=GZQ,出發站的局碼,GZQ是指局碼,表示廣州。

orderRequest.to_station_telecode=XAY,同樣這個是指到達站的局碼,XAY表示西安。

orderRequest.train_no=這個參數是可選的,如果填的話,不是填車次,而是車次的電報碼。

如圖查詢,加上列車車次,那麼查詢url則變為:

http://dynamic.12306.cn/otsquery/query/queryRemanentTicketAction.do?method=queryLeftTicket&orderRequest.train_date=2013-11-25&orderRequest.from_station_telecode=GZQ&orderRequest.to_station_telecode=XAY&orderRequest.train_no=6c0000G83201&trainPassType=QB&trainClass=QB%23D%23Z%23T%23K%23QT%23&includeStudent=00&seatTypeAndNum=&orderRequest.start_time_str=00%3A00--24%3A00

多了6c0000G83201,這個就是車次的電報碼。


那麼局碼怎麼取得的呢,還是用捕獲,在查詢余票頁面的攔截中,有一個請求:

http://dynamic.12306.cn/otsquery/js/common/favorite_name.js?version=1.55,當然可能version會有變化。這個返回的結果截了部分如下:

@bji|北京|BJP|0@sha|上海|SHH|1@tji|天津|TJP|2@cqi|重慶|CQW|3@csh|長沙|CSQ|4@cch|長春|CCT|5@cdu|成都|CDW|6@fzh|福州|FZS|7@gzh|廣州|GZQ|8@gya|貴陽|GIW......

其中大寫那部分是局碼,這個大家有興趣可以自己下載下來然後重新組織保存。


而車次的電報碼如何來的?當然如果想單純的查詢余票則電報碼參數可以不考慮。如果想查詢某一個車次的余票則結合另一篇文章 讀取12306票價信息 文中有查詢出票價信息的字符串中,有一個參數是車次的電報碼。如下

parent.mygrid.addRow(1,"2,K1168^skbcx.jsp?cxlx=cc&date=20131126&trainCode=K1168_6b000K116801,廣州^skbcx.jsp?cxlx=czjgcc&zm=&date=20131126&stationName_passTrain=%E5%B9%BF%E5%B7%9E^self,西安^skbcx.jsp?cxlx=czjgcc&zm=&date=20131126&stationName_passTrain=%E8%A5%BF%E5%AE%89^self,--,--,--,--,--,724/757,408/421/436,--,240,08:57,12:11,27:14,海口^skbcx.jsp?cxlx=czjgcc&zm=&date=20131126&stationName_passTrain=%E6%B5%B7%E5%8F%A3^self,西安^skbcx.jsp?cxlx=czjgcc&zm=&date=20131126&stationName_passTrain=%E8%A5%BF%E5%AE%89^self,快速,有",1);

其中 trainCode=K1168_6b000K116801,下劃線後的就是K1168次列車的電報碼,所以如果針對某一列車查詢余票 則結合該文章使用。


這個查詢相對簡單,不過需要提前獲取所有車站的局碼。

實現方法如下:

   

public static string DoGetTrainTicketLeft(string fromTime, string fromStation,string arriveStation,string trainTeleCode)
      {
          string result = string.Empty;
          try
          {
              //0-時間 1-出發站 2-達到 3-車次
              string trainTicketLeftUrl =
      @"http://dynamic.12306.cn/otsquery/query/queryRemanentTicketAction.do?method=queryLeftTicket&orderRequest.train_date={0}&orderRequest.from_station_telecode={1}&orderRequest.to_station_telecode={2}&orderRequest.train_no={3}&trainPassType=QB&trainClass=QB%23D%23Z%23T%23K%23QT%23&includeStudent=00&seatTypeAndNum=&orderRequest.start_time_str=00%3A00--24%3A00";
              trainTicketLeftUrl = string.Format(trainTicketLeftUrl, fromTime, fromStation, arriveStation, trainTeleCode);
              HttpWebRequest request = (HttpWebRequest)WebRequest.Create(trainTicketLeftUrl);
              request.Accept = @"application/json, text/javascript, */*";
              request.UserAgent = @"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
              request.Referer = @"http://dynamic.12306.cn/otsquery/query/queryRemanentTicketAction.do?method=init";
              request.ContentType = @"application/x-www-form-urlencoded";
              request.Method = "GET";
              using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
              {
                  using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                  {
                      result = reader.ReadToEnd();
                  }
              }
          }
          catch { }
          return result;
      }

調用,

 DoGetTrainTicketLeft("2013-11-26", "GZQ", "XAY", "6b000K116801");

 至於後三個參數的填充,大家自己想辦法下載網上的車站數據吧。因為我實現該方法時使用的是正式的鐵路局數據,數據庫中包含了車站和車站局碼的數據。而列車電報碼則是根據票價查詢中獲取而來。


 調用上面方法,返回數據如下:

{"datas":"0,<span id='id_6b000K116801' class='base_txtdiv'   src='/otsquery/images/tips/last.gif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;西安&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;12:11,27:14,--,--,--,--,--,8,181,--,156,198,--,","time":"20:19"}

 顯然這是一個json字符串,做相應的截取處理也是可以得到你想要的余票數據的。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved