调用顺序
登录
- Get captcha-image
- captcha-check
- /passport/web/login => uamtk
- /passport/web/auth/uamtk => newapptk
- /otn/uamauthclient => apptk 此步要调用,它会在cookie里设置tk=apptk
点击 查询 按钮
- Query Left Ticket https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2018-01-28&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=UUH&purpose_codes=ADULT
点击 预订 按钮
- checkUser 检查用户登录状态还是否有效(如果登录无效会弹出登录窗口,页面不跳转) https://kyfw.12306.cn/otn/login/checkUser
- submitOrderRequest 预提交订单 https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest
点击 ** 按钮
Login
点击 登录 会调用
loginClick
in https://kyfw.12306.cn/otn/resources/merged/login_UAM_js.js?scriptVersion=1.9075
verifyLoginUser()
ajax:
{
"url": "https://kyfw.12306.cn/passport/web/login",
"data": {
"username": "",
"password": "",
"appid": "otn"
},
"type": "POST",
"dataType": "json",
"xhrFields": {
withCredentials: true
},
"success": `function(e) {
dhtmlx.modalbox.hide(k);
if (e.result_code == 0) {
$.submitLogin()
} else {
dhtmlx.alert({
title: messages["message.error"],
ok: messages["button.ok"],
text: e.result_message,
type: "alert-error",
callback: function() {}
});
if ("Y" == ifShowRandCode && "Y" == openRandCodeCheck) {
$.refreshImg("login", "sjrand");
$("#randCode").val("")
}
$("#password").val("");
return false
}
}`
}
Cookie: JSESSIONID=E422CD90221E139137A23881AB380AA5; route=495c805987d0f5c8c84b14f60212447d; BIGipServerotn=1490616586.50210.0000; BIGipServerpassport=887619850.50215.0000; RAIL_EXPIRATION=1516888514432; RAIL_DEVICEID=BUDllF83rIg8WbCrkztInw4nMU-21NIjmLDk5wS_lbQ1RlQwbORtlKtfFAGXHfv7VVlz6s6m38DnkcJIHmkaz4dh4OIM-ybyZ4cQpBZtDosbFu53hl8WWH-iYIvo3HsNIZfkS0qpfQMVgf9Zy1h-ytrTfozna-B4; current_captcha_type=Z; _jc_save_wfdc_flag=dc; _jc_save_fromStation=%u4E0A%u6D77%2CSHH; _jc_save_toStation=%u5F90%u5DDE%u4E1C%2CUUH; _jc_save_showIns=true; _jc_save_toDate=2018-01-24; _jc_save_fromDate=2018-02-10; acw_tc=AQAAAJaiRTFGTQcAWSxrcbmdQsQieRp9
SubmitOrderRequest
Check User
正常返回结果:
{
"validateMessagesShowId": "_validatorMessage",
"status": true,
"httpstatus": 200,
"data": {
"flag": true
},
"messages": [],
"validateMessages": {}
}
Submit Order Request
secretStr 字符串要先解码,因为放到 Request 请求里后会再编码
{
"validateMessagesShowId": "_validatorMessage",
"status": false,
"httpstatus": 200,
"messages": ["提交失败,请重试..."],
"validateMessages": {}
}
Passengers
POST https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs
Request Headers:
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:JSESSIONID=913D6088A0465098BD60C1AD8ADE0A98; tk=CjnCaQkHmP-fv_aLZRge9X5KXkg4mM87bUx9PBa5M-Ufsa1a0; route=495c805987d0f5c8c84b14f60212447d; BIGipServerotn=1490616586.50210.0000; BIGipServerpassport=887619850.50215.0000; RAIL_EXPIRATION=1516888514432; RAIL_DEVICEID=BUDllF83rIg8WbCrkztInw4nMU-21NIjmLDk5wS_lbQ1RlQwbORtlKtfFAGXHfv7VVlz6s6m38DnkcJIHmkaz4dh4OIM-ybyZ4cQpBZtDosbFu53hl8WWH-iYIvo3HsNIZfkS0qpfQMVgf9Zy1h-ytrTfozna-B4; current_captcha_type=Z; _jc_save_wfdc_flag=dc; _jc_save_fromStation=%u4E0A%u6D77%2CSHH; _jc_save_toStation=%u5F90%u5DDE%u4E1C%2CUUH; _jc_save_showIns=true; acw_tc=AQAAAJaiRTFGTQcAWSxrcbmdQsQieRp9; _jc_save_toDate=2018-01-25; _jc_save_fromDate=2018-01-27
Host:kyfw.12306.cn
Origin:https://kyfw.12306.cn
Referer:https://kyfw.12306.cn/otn/confirmPassenger/initDc
Form data:
_json_att:
REPEAT_SUBMIT_TOKEN:f11482ceb95fe169b81666d1703fb1fb
Submit Order
提交订单 会调用两个API
/confirmPassenger/checkOrderInfo
/confirmPassenger/getQueueCount
Check Order Info
POST https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo
Body:
cancel_flag=2&bed_level_order_num=000000000000000000000000000000&passengerTicketStr=1%2C0%2C1%2C%E7%8E%8B%E4%BD%93%E6%96%87%2C1%2C372925198804206310%2C%2CN&oldPassengerStr=%E7%8E%8B%E4%BD%93%E6%96%87%2C1%2C372925198804206310%2C1_&tour_flag=dc&randCode=&whatsSelect=1&_json_att=&REPEAT_SUBMIT_TOKEN=6a6dc76a1dd998299d4655d0a209e335
Response:
{
"validateMessagesShowId": "_validatorMessage",
"status": true,
"httpstatus": 200,
"data": {
"ifShowPassCode": "N",
"canChooseBeds": "N",
"canChooseSeats": "N",
"choose_Seats": "MOP9",
"isCanChooseMid": "N",
"ifShowPassCodeTime": "1",
"submitStatus": true,
"smokeStr": ""
},
"messages": [],
"validateMessages": {}
}
Submit Order Request
function submitOrderRequest
in https://kyfw.12306.cn/otn/resources/merged/queryLeftTicket_end_js.js?scriptVersion=1.9075
提交前检查用户登录状态,如果登录状态失效则弹出窗口重新登录,登录成功后调用提交函数。如果检查用户状态有效则直接提交订单。
Get Queue Count
POST https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount
Request Body:
train_date:Thu Jan 25 2018 00:00:00 GMT+0800 (China Standard Time)
train_no:5e00000K76B3
stationTrainCode:K76
seatType:1
fromStationTelecode:SNH
toStationTelecode:XCH
leftTicket:XTBVCUUTulB%2BreE0gJQF2Y8E4wr%2BozjlZp%2FN0%2FRQmpgZH5CxA84tgtkbBXA%3D
purpose_codes:00
train_location:H3
_json_att:
REPEAT_SUBMIT_TOKEN:6a6dc76a1dd998299d4655d0a209e335
Response:
{
"validateMessagesShowId": "_validatorMessage",
"status": true,
"httpstatus": 200,
"data": {
"count": "7",
"ticket": "1,43",
"op_2": "false",
"countT": "0",
"op_1": "true"
},
"messages": [],
"validateMessages": {}
}
/data/ticket
= 1,43 :本次列车, 硬座余票1张,无座余票43张
Confirm Order
点击 确认 会调用
qr_submitClickEvent
in https://kyfw.12306.cn/otn/resources/merged/passengerInfo_js.js?scriptVersion=1.9075
ticketInfoForPassengerForm.isAsync
正在处理,请稍候。
{
"passengerTicketStr": "1,0,1,王体文,1,372925198804206310,,N",
"oldPassengerStr": "王体文,1,372925198804206310,1_",
"randCode": "",
"purpose_codes": "00",
"key_check_isChange": "3A5702D3018024C64714BEE1BEEDF095AC432B28FEC97779C6D49EF8",
"leftTicketStr": "XTBVCUUTulB%2BreE0gJQF2Y8E4wr%2BozjlZp%2FN0%2FRQmpgZH5CxA84tgtkbBXA%3D",
"train_location": "H3",
"choose_seats": "",
"seatDetailType": "000",
"whatsSelect": "1"
}
confirmPassenger/confirmSingleForQueue
{
"url": "/otn/confirmPassenger/confirmSingleForQueue",
"data": {
"passengerTicketStr": "1,0,1,王体文,1,372925198804206310,,N",
"oldPassengerStr": "王体文,1,372925198804206310,1_",
"randCode": "",
"purpose_codes": "00",
"key_check_isChange": "3A5702D3018024C64714BEE1BEEDF095AC432B28FEC97779C6D49EF8",
"leftTicketStr": "XTBVCUUTulB%2BreE0gJQF2Y8E4wr%2BozjlZp%2FN0%2FRQmpgZH5CxA84tgtkbBXA%3D",
"train_location": "H3",
"choose_seats": "",
"seatDetailType": "000",
"whatsSelect": "1",
"roomType": "00",
"dwAll": "N"
},
"type": "POST",
"dataType": "json",
"success": `function(Z) {
if (Z.status) {
if (!Z.data.submitStatus) {
l("出票失败!", false, "原因: " + Z.data.errMsg + '<a id="xg_close_win_id" >点击修改</a>', false, "lose");
$("#xg_close_win_id").click(function() {
closeWin("transforNotice_id", true);
$("#i-ok").css("display", "none")
})
} else {
var aa = new OrderQueueWaitTime(V,v,Q);
aa.start()
}
} else {
l("订票失败!", true, "很抱歉!请关闭窗口重新预定车票", true, "lose")
}
}`,
"error": `function(Z, ab, aa) {
l("订票失败!", true, "很抱歉!网络忙,请关闭窗口稍后再试。", true, "lose");
return
}`
}
confirmPassenger/confirmGoForQueue
confirmPassenger/confirmBackForQueue
confirmPassenger/confirmResignForQueue
Problems
302 Moved Temporarily
Request Headers 设置不完整会出现此问题。
服务器经常返回 302 错误,具体 Headers 如下。 Response headers:
{
"location": "http://www.12306.cn/mormhweb/logFiles/error.html",
"server": "Cdn Cache Server V2.0",
"mime-version": "1.0",
"date": "Tue, 30 Jan 2018 05:13:38 GMT",
"content-type": "text/html",
"content-length": "0",
"expires": "Tue, 30 Jan 2018 05:13:38 GMT",
"x-via": "1.0 tongdianxin79:2 (Cdn Cache Server V2.0)",
"connection": "close",
"x-cdn-src-port": "42207"
}
https://segmentfault.com/a/1190000006673084
https://stackoverflow.com/questions/973098/what-does-http-1-1-302-mean-exactly
References
https://www.jianshu.com/p/016307d4d1eb
https://www.cnblogs.com/dare/p/8286781.html
http://www.webkf.net/index/62/94430.html
Python
python -m pip install Pillow
Comments