编程乐趣:C#实现读取12306余票信息


读取余票也是用同样的方式(读取票价信息

也就是该页面。


使用IE9捕获查询时的参数:


因为这个查询是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' οnmοuseοver=javascript:onStopHover('6b000K116801#GZQ#XAY') οnmοuseοut='onStopOut()'>K1168<\/span>,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;广州&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;08:57,<img 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字符串,做相应的截取处理也是可以得到你想要的余票数据的。
 
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值