12306 的 api 是 https 请求,所以在网络请求中需要添加证书,根证书下载地址就在 12306 首页上可以看到,下载链接请戳我
请求中可能需要使用到火车出发站、始发站、到达站、终点站所对应的代号,我已经将相应的数据转成了 WPS 的表格,点我查看文件,下载后可以用 WPS 或 Excel 打开即可,或自行转成数据库文件,文件中的 teleCode 列就是相应的站点代号了。
请求方式:GET
url:https://kyfw.12306.cn/otn/leftTicket/query
url:https://kyfw.12306.cn/otn/leftTicket/queryX
ps:12306 网页版的 api 不是很稳定,定期会更改,更改套路是上面 url 中的 leftTicket/query 后面可能会增加一个大写的字母。例如: https://kyfw.12306.cn/otn/leftTicket/queryA,此时返回的 json 中有一个 c_url 字段,将其拼接在 https://kyfw.12306.cn/otn/ 后就是最新的 api 接口。可见 issue#1、issue#22
参数:
| 参数名 | 参数意义 | 参数类型 |
|---|---|---|
| leftTicketDTO.train_date | 乘车日期,yyyy-MM-dd 格式(例:2017-02-05) |
String |
| leftTicketDTO.from_station | 始发站码,取值参考数据库 | String |
| leftTicketDTO.to_station | 终点站码,取值参考数据库 | String |
| purpose_codes | 乘车人员码,取值(普通 ADULT,学生 0X00) |
String |
url 示例:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-02-05&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=0X00(2017年02月05日,北京到上海的普通乘客票)
json 示例:
{
"validateMessagesShowId": "_validatorMessage",
"status": true,
"httpstatus": 200,
"data": [
{
"queryLeftNewDTO": {
"train_no": "240000G1230Z",
"station_train_code": "G123",
"start_station_telecode": "VNP",
"start_station_name": "北京南",
"end_station_telecode": "AOH",
"end_station_name": "上海虹桥",
"from_station_telecode": "VNP",
"from_station_name": "北京南",
"to_station_telecode": "AOH",
"to_station_name": "上海虹桥",
"start_time": "11:05",
"arrive_time": "16:50",
"day_difference": "0",
"train_class_name": "",
"lishi": "05:45",
"canWebBuy": "N",
"lishiValue": "345",
"yp_info": "sE3veQEvivDNrJQAIUCZI5PtvU7ENkijF8pSvENHwys5z311",
"control_train_day": "20301231",
"start_train_date": "20170205",
"seat_feature": "O3M393",
"yp_ex": "O090M0",
"train_seat_feature": "3",
"seat_types": "O9M",
"location_code": "P3",
"from_station_no": "01",
"to_station_no": "11",
"control_day": 29,
"sale_time": "0800",
"is_support_card": "0",
"controlled_train_flag": "0",
"controlled_train_message": "正常车次,不受控",
"train_type_code": "2",
"start_province_code": "31",
"start_city_code": "0357",
"end_province_code": "33",
"end_city_code": "0712",
"yz_num": "--",
"rz_num": "--",
"yw_num": "--",
"rw_num": "--",
"gr_num": "--",
"zy_num": "无",
"ze_num": "无",
"tz_num": "--",
"gg_num": "--",
"yb_num": "--",
"wz_num": "--",
"qt_num": "--",
"swz_num": "无"
},
"secretStr": "",
"buttonTextInfo": "预订"
},
{
"queryLeftNewDTO": {
"train_no": "2400000G2108",
"station_train_code": "G21",
"start_station_telecode": "VNP",
"start_station_name": "北京南",
"end_station_telecode": "AOH",
"end_station_name": "上海虹桥",
"from_station_telecode": "VNP",
"from_station_name": "北京南",
"to_station_telecode": "AOH",
"to_station_name": "上海虹桥",
"start_time": "16:00",
"arrive_time": "21:14",
"day_difference": "0",
"train_class_name": "",
"lishi": "05:14",
"canWebBuy": "Y",
"lishiValue": "314",
"yp_info": "WmvP8FMB9uVqGcP1F4NHBnyROKJlVXgN5%2BROQdLyLq2LFnqJ",
"control_train_day": "20301231",
"start_train_date": "20170205",
"seat_feature": "O3M393",
"yp_ex": "O0M090",
"train_seat_feature": "3",
"seat_types": "OM9",
"location_code": "P2",
"from_station_no": "01",
"to_station_no": "06",
"control_day": 29,
"sale_time": "0800",
"is_support_card": "0",
"controlled_train_flag": "0",
"controlled_train_message": "正常车次,不受控",
"train_type_code": "2",
"start_province_code": "31",
"start_city_code": "0357",
"end_province_code": "33",
"end_city_code": "0712",
"yz_num": "--",
"rz_num": "--",
"yw_num": "--",
"rw_num": "--",
"gr_num": "--",
"zy_num": "无",
"ze_num": "无",
"tz_num": "--",
"gg_num": "--",
"yb_num": "--",
"wz_num": "--",
"qt_num": "--",
"swz_num": "1"
},
"secretStr": "JjGzeN7ylJHEQP%2BV5SJrrRMAYJHWAIa%2Br0ajzk82EdzFbABAe6ePuEJKqxjxJe2Eas8uwD4ygP1j%0Avgtn%2F4o4c60VBBTn80KZ7wVd2lmzRGO7WSHNsp%2F%2F0OH7VLER0lhKFd3%2BZbu6gRG%2BeBv%2FJuIJkFUj%0A71KnMlVLZQtNXuZR6PnXcLc3pcb7eflTamalptsn9Nbb5oiya8YM2vKGvrqmYoKY2CJlAFv8ZObF%0AYdKyo4tYLnJkMfZdyCSTDq%2F17ZLvwaK2eOMukVZUAZ6fzhPNRqFsC6L%2FXJpTXCZcBJAW%2Fh17XSQN%0AWImvMFtTCtY%3D",
"buttonTextInfo": "预订"
}
],
"messages": [],
"validateMessages": {}
}
解析:
train_no:车次码(用作票价查询)station_train_code:车次号from_station_name:出发站from_station_telecode:出发站码to_station_name:到达站to_station_telecode:到达站码start_station_name:始发站start_station_telecode:始发站码end_station_name:终点站end_station_telecode:终点站码start_time:出发时间arrive_time:到达时间day_difference:历时天数train_class_name:???lishi:历时小时分钟数canWebBuy:Y可以预订、N不可预订、IS_TIME_NOT_BUY没到预定时间lishiValue:历时分钟数yp_info:一票信息,应该是智行火车票所需要的信息control_train_day:???start_train_date:发车日seat_types:座位类型(用作票价查询)from_station_no:出发站码(用作票价查询)to_station_no:到达站码(用作票价查询)swz_num:商务座tz_num:特等座zy_num:一等座数ze_num:二等座数gr_num:高级软卧数rw_num:软卧数yw_num:硬卧数rz_num:软座数yz_num:硬座数wz_num:无座数qt_num:其他座数gg_num:???secretStr:车票预订标识
请求方式:GET
url:https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice
参数:
| 参数名 | 参数意义 | 参数类型 |
|---|---|---|
| train_no | 车次码 | String |
| from_station_no | 出发站码 | int |
| to_station_no | 到达站码 | int |
| seat_types | 座位类型 | String |
| train_date | 乘车日期,yyyy-MM-dd 格式(例:2017-02-05) |
String |
json 示例:
{
"validateMessagesShowId": "_validatorMessage",
"status": true,
"httpstatus": 200,
"data": {
"3": "2835",
"A1": "¥156.5",
"1": "1565",
"A4": "¥455.5",
"A3": "¥283.5",
"4": "4555",
"OT": [],
"WZ": "¥156.5",
"train_no": "5500001462H1"
},
"messages": [],
"validateMessages": {}
}
解析:
MIN:其他座票价WZ:无座票价A1:硬座票价A2:软座票价A3:硬卧票价A4:软卧票价A6:高级软卧O:二等座票价M:一等座票价P:特等座票价A9:商务座票价train_no:车次代码