C#调用12306API做余票查询
来源:互联网 发布:淘宝坑店 编辑:程序博客网 时间:2024/06/05 05:29
本文叙述的是使用C#调用12306的API做余票查询程序的方法。
先看一下程序运行截图。本程序使用WPF。
1. 了解12306API
登陆12306网站,点击余票查询,我们查询从北京到上海的火车票。
抓取到的数据包如下:
请求报文头:
这就是我们封装查询报文时需要模仿的格式。
返回报文为一个json格式的字符串,下面是一个样例:
{"validateMessagesShowId":"_validatorMessage","status":true,"httpstatus":200,"data":{"datas":[{"train_no":"240000T1090K","station_train_code":"T109","start_station_telecode":"BJP","start_station_name":"北京","end_station_telecode":"SHH","end_station_name":"上海","from_station_telecode":"BJP","from_station_name":"北京","to_station_telecode":"SHH","to_station_name":"上海","start_time":"19:33","arrive_time":"10:44","day_difference":"1","train_class_name":"","lishi":"15:11","canWebBuy":"Y","lishiValue":"911","yp_info":"10177531664047650000101775000060879500063030450000","control_train_day":"20201231","start_train_date":"20150110","seat_feature":"W343136333","yp_ex":"1040106030","train_seat_feature":"3","seat_types":"14163","location_code":"P4","from_station_no":"01","to_station_no":"11","control_day":59,"sale_time":"1000","is_support_card":"0","note":"","gg_num":"--","gr_num":"6","qt_num":"--","rw_num":"无","rz_num":"--","tz_num":"--","wz_num":"166","yb_num":"--","yw_num":"无","yz_num":"无","ze_num":"--","zy_num":"--","swz_num":"--"},{"train_no":"240000D3130B","station_train_code":"D313","start_station_telecode":"VNP","start_station_name":"北京南","end_station_telecode":"SHH","end_station_name":"上海","from_station_telecode":"VNP","from_station_name":"北京南","to_station_telecode":"SHH","to_station_name":"上海","start_time":"19:34","arrive_time":"07:27","day_difference":"1","train_class_name":"动车","lishi":"11:53","canWebBuy":"Y","lishiValue":"713","yp_info":"O030900114O0309030154061500346","control_train_day":"20301231","start_train_date":"20150110","seat_feature":"O343W3","yp_ex":"O0O040","train_seat_feature":"3","seat_types":"OO4","location_code":"P3","from_station_no":"01","to_station_no":"04","control_day":59,"sale_time":"1230","is_support_card":"0","note":"","gg_num":"--","gr_num":"--","qt_num":"--","rw_num":"346","rz_num":"--","tz_num":"--","wz_num":"15","yb_num":"--","yw_num":"--","yz_num":"--","ze_num":"114","zy_num":"--","swz_num":"--"},{"train_no":"240000D31102","station_train_code":"D311","start_station_telecode":"VNP","start_station_name":"北京南","end_station_telecode":"SHH","end_station_name":"上海","from_station_telecode":"VNP","from_station_name":"北京南","to_station_telecode":"SHH","to_station_name":"上海","start_time":"21:16","arrive_time":"08:58","day_difference":"1","train_class_name":"动车","lishi":"11:42","canWebBuy":"Y","lishiValue":"702","yp_info":"O030900158O0309030174061500296","control_train_day":"20301231","start_train_date":"20150110","seat_feature":"O343W3","yp_ex":"O0O040","train_seat_feature":"3","seat_types":"OO4","location_code":"P2","from_station_no":"01","to_station_no":"04","control_day":59,"sale_time":"1230","is_support_card":"0","note":"","gg_num":"--","gr_num":"--","qt_num":"--","rw_num":"296","rz_num":"--","tz_num":"--","wz_num":"17","yb_num":"--","yw_num":"--","yz_num":"--","ze_num":"158","zy_num":"--","swz_num":"--"},{"train_no":"240000D32109","station_train_code":"D321","start_station_telecode":"VNP","start_station_name":"北京南","end_station_telecode":"SHH","end_station_name":"上海","from_station_telecode":"VNP","from_station_name":"北京南","to_station_telecode":"SHH","to_station_name":"上海","start_time":"21:23","arrive_time":"09:12","day_difference":"1","train_class_name":"动车","lishi":"11:49","canWebBuy":"Y","lishiValue":"709","yp_info":"O030900210O0309030154061500236","control_train_day":"20301231","start_train_date":"20150110","seat_feature":"O343W3","yp_ex":"O0O040","train_seat_feature":"3","seat_types":"OO4","location_code":"P2","from_station_no":"01","to_station_no":"05","control_day":59,"sale_time":"1230","is_support_card":"0","note":"","gg_num":"--","gr_num":"--","qt_num":"--","rw_num":"236","rz_num":"--","tz_num":"--","wz_num":"15","yb_num":"--","yw_num":"--","yz_num":"--","ze_num":"210","zy_num":"--","swz_num":"--"}],"flag":true,"searchDate":"2015年01月10号 周六"},"messages":[],"validateMessages":{}}在这个json串中包含了查询到的车辆余票信息,也包含查询者的信息。我们只需要提取其中有用的部分。现将其中有用的部分列举如下:
其中有一些字段没有标注释,目前意义未知
通过解析这个json串,就能完成余票查询的工作。
2. 具体操作方法
根据上面抓取到的数据包,我们知道API的地址为:
string uri = @"https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes={0}&queryDate={1}&from_station={2}&to_station={3}";uri = string.Format(uri, purpose, date, from, to);可以看出,其中一共有4个参数,perpose表示票的种类(成人票,学生票等),date表示查询火车开车的日期(格式为:yyyy-mm-dd),from表示出发车站代码,end表示到达车站代码。代码均为3位数大写英文字母,每一个代码唯一对应一个车站。
车站代码可以到下面链接处下载:
http://download.csdn.net/detail/xiahn1a/8348211
对于上面给出的链接中下载到的代码的处理方法:
文档中代码是如下格式:
bjb|北京北|VAP|beijingbei|bjb|0@bjd|北京东|BOP|beijingdong|bjd|1车站间使用@分割,每条信息间使用|分割。我们所需要的只是第2项名称和第3项代码,其他的拼音,编号等不是我们所需要的内容。
根据代码文档我们可以建立一个站名到代码的映射关系。
给一个链接的例子,在2015年1月10日查询从北京到上海的成人票:
https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2015-01-10&from_station=BJP&to_station=SHH剩下的就是按照上面截图的格式封装报文即可,需要注意的是我们需要采用ssl,有一个验证证书的过程,还需要建立一个CookieContainer。
对于返回的json格式串,使用NewtonSoft.Json类中的相应函数将json字符串转换为jclass对象,然后可以直接通过Linq语句查询出所需要的对象。
相关的封装报文步骤代码如下:
private CookieContainer cc = new CookieContainer();public void GetInfo(string purpose, string date, string from, string to){ try { string uri = @"https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes={0}&queryDate={1}&from_station={2}&to_station={3}"; uri = string.Format(uri, purpose, date, from, to); ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.CookieContainer = cc; request.ProtocolVersion = HttpVersion.Version10; request.Accept = @"*/*"; request.UserAgent = @"Mozilla/5.0 (Windows NT 6.4; WOW64; Trident/7.0; rv:11.0) like Gecko"; request.Referer = @"https://kyfw.12306.cn/otn/lcxxcx/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)) { string res = reader.ReadToEnd(); jclass jc1 = JsonConvert.DeserializeObject<jclass>(res); getData(jc1); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } return ;}private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors){ return true; //总是接受 }
本文完成于2015.1.10,到目前为止,该API仍可用。
0 0
- C#调用12306API做余票查询
- 12306火车票查询api调用文档
- 足球联赛查询api调用
- C#调用API
- C#中调用API
- C#调用API
- C#调用API
- C#中调用API
- C#调用windows API
- C#中调用API
- C#中调用API
- C#中调用API
- C#中调用API
- C#中调用API
- C#调用API
- C#中调用API
- C#调用API[转]
- C#调用API函数
- sdf
- 数据库经验【VB】2
- umask 022解析
- 3n+1问题大数据如何处理?
- C++超基础:类模板——下、类模版的特化
- C#调用12306API做余票查询
- spring报“Could not resolve placeholder”错误
- fssd
- 中断下半部-工作队列(比较tasklet和工作队列,推荐)
- 各种数据类型的输出占位符
- 九度OJ&北京航空航天大学2009机试题题解
- fsd
- JAVA 集合框架总结
- Java基础知识(一)