获取12306余票信息 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ufologist
V2EX    分享发现

获取12306余票信息

  •  
  •   ufologist 2013-01-17 16:29:26 +08:00 5686 次点击
    这是一个创建于 4731 天前的主题,其中的信息可能已经有所发展或是发生改变。
    警告: 本程序是出于学习目的, 仅限于分析研究时用, 不可用于非法用途
    由于程序所造成的损失本人概不负责, 如有造成不便请通知本人删除程序

    欢迎大家去[GitHub Gist](https://gist.github.com/4554460)围观提提意见, 常感谢
    希望每个人都能买到回家的车票, 合家团圆...

    http://www.douban.com/note/258531479/


    /**
    * 获取12306余票信息
    *
    * 查询列车的余票信息
    * GET https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=getQueueCount&train_date=2013-02-05&train_no=240000D31307&station=D313&from=VNP&to=SHH
    *
    * URL参数解析
    * train_date // 不用说了吧
    * train_no // 列车ID, 在余票查询结果车次的span中可以得到
    * station // 车次
    * from // 发站CODE 参考: dynamic.12306.cn/otsweb/js/common/station_name.js?version=5.42
    * to // 到站CODE
    *
    * 返回数据
    * {"countT":0,"count":116,"ticket":"1*****31794*****00001*****00943*****0001","op_1":true,"op_2":false}
    * op_2=true -> 目前排队人数已经超过余票张数,请您选择其他席别或车次,特此提醒。
    * countT -> 目前排队人数
    * ticket -> 余票信息
    *
    * @param 同URL参数, 都是必要参数, 外加一个seat参数(席别)
    * 例如:
    * get12306RemainTicket({
    * train_date: "2013-02-02",
    * train_no: '240000T1090G',
    * station: 'T109',
    * from: 'VNP',
    * to: 'SHH',
    * seat: 1
    * });
    */
    function get12306RemainTicket(param) {
    var seat = param.seat;
    delete param.seat;
    $.ajax({
    url: 'https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=getQueueCount', // 必须HTTPS
    type: 'GET',
    data: param,
    dataType: 'json',
    success: function(data) {
    console.log(data);
    console.log(getTicketCountDesc(data.ticket, seat));
    },
    error: function() {
    console.error(arguments);
    }
    });
    }

    /**
    * 解密12306预订按钮(链接)代表什么含义
    * 解密ypInfoDetail
    *
    * @author Sun
    * @version 1.0 2013-1-17
    *
    * @param mark 上面返回数据中的ticket, 也就是ypInfoDetail(查看余票查询结果中预订链接的内容)
    * mark规律解析
    * 1*****31794*****00001*****00943*****0001按照10个字符串为一组信息, 因此拆分如下
    * 1*****3179
    * 4*****0000
    * 1*****0094
    * 3*****0001
    * 星号前面的第一位为席别, 星号后面的为余票数, 如果这个数字大于3000则表示无座票, 应减去3000后才是真正的余票数
    * 因此总体规律为 -> 席别*****余票数
    * @param seat 席别类型(硬座: 1, 硬卧: 3, 软卧: 4), 在预订页面中获取$("#passenger_1_seat").val()
    * @see dynamic.12306.cn/otsweb/js/order/save_passenger_info.js?version=5.42
    */
    function getTicketCountDesc(mark, seat) {
    var ticketCountDesc = "";
    // 本次列车您选择的席别尚有余票94张
    var seatTicket = -1; // 所选席别余票多少张
    // 无座179张
    var withoutSeatTicket = -1; // 无座票多少张

    var i = 0;
    while (i < mark.length) {
    // 1*****3179
    var group = mark.substr(i, 10);
    // 1(席别)
    var seatType = group.substr(0, 1);
    // 1 == 1(硬座)
    if (seatType == seat) {
    // 3179
    var count = group.substr(6, 4);
    while (count.length > 1 && count.substr(0, 1) == "0") { // count为0000的情况, count最终等于0
    count = count.substr(1, count.length);
    }
    // 3179
    count = parseInt(count);
    if (count < 3000) {
    seatTicket = count;
    } else {
    // 179
    withoutSeatTicket = (count - 3000);
    }
    }
    i = i + 10;
    }

    if (seatTicket > -1) {
    ticketCountDesc = '本次列车您选择的席别尚有余票 ' + seatTicket + ' 张';
    }
    if (withoutSeatTicket > -1) {
    ticketCountDesc += ' 无座 ' + withoutSeatTicket + ' 张';
    }
    return ticketCountDesc;
    }







    /* 以下为参考信息 */
    /* ------------------------------------------- */

    /**
    * 余票查询中的预订链接
    *
    * 示例数据: 2013-02-02 北京→上海 D321
    * <a name="btn130_2" class="btn130_2" style="text-decoration:none;" Onclick="Javascript:getSelected('D321#11:42#21:22#240000D32120#VNP#SHH#09:04#北京南#上海#01#04#O*****01644*****0244O*****3017#57463B183AA6FE5168F52051EF2411B00CBB7D60B8C691B50200094B#P2')">预订</a>
    * @see dynamic.12306.cn/otsweb/js/order/query_common_func.js?version=5.42
    */
    function getSelected(selectStr) {
    // 参数格式:#号分隔
    var selectStr_arr = selectStr.split("#");
    var station_train_code=selectStr_arr[0];
    var lishi=selectStr_arr[1];
    var starttime=selectStr_arr[2];
    var trainno=selectStr_arr[3];
    var from_station_telecode=selectStr_arr[4];
    var to_station_telecode=selectStr_arr[5];
    var arrive_time=selectStr_arr[6];
    var from_station_name=selectStr_arr[7];
    var to_station_name=selectStr_arr[8];
    var from_station_no=selectStr_arr[9];
    var to_station_no=selectStr_arr[10];
    var ypInfoDetail=selectStr_arr[11];
    var mmStr = selectStr_arr[12];
    var locatiOnCode= selectStr_arr[13];

    // 参数值说明
    // ----------
    // 1. station_train_code // 车次(D321)
    // 2. lishi // 历时(11:42)
    // 3. starttime // 发车时间(21:22)
    // 4. trainno // 列车ID(240000D32120), 可以从查询数据的table中获得该信息<span Onmouseover="onStopHover('240000D32120#VNP#SHH')" id="id_240000D32120">D321</span>
    // 5. from_station_telecode // 发站CODE(VNP)
    // 6. to_station_telecode // 到站CODE(SHH)
    // 7. arrive_time // 到站时间(09:04)
    // 8. from_station_name // 发站名(北京南)
    // 9. to_station_name // 到站名(上海)
    // 10. from_station_no // 发站序号(该趟列车路线上的序号)(01)
    // 11. to_station_no // 到站序号(该趟列车路线上的序号)(04)
    // 12. ypInfoDetail // yp -> 余票(O*****01644*****0244O*****3017), 在预订页面left_ticket会补全星号O1234501644123450244O123453017, 可以认为这就代表票的ID, 具体含义请参考getTicketCountDesc
    // 13. mmStr // token(57463B183AA6FE5168F52051EF2411B00CBB7D60B8C691B50200094B)
    // 14. locationCode // TODO 随车次变化, 猜测是此趟车的到站CODE(P2)

    var flag = true;
    if (checkBeyondMixTicketNum()) {
    flag = false;
    return;
    }
    if (flag) {
    submitRequest(station_train_code,lishi,starttime,trainno,from_station_telecode,to_station_telecode,arrive_time,from_station_name,to_station_name,from_station_no,to_station_no,ypInfoDetail,mmStr,locationCode);
    }
    }

    /**
    * 请求预订
    *
    * @see dynamic.12306.cn/otsweb/js/order/query_common_bind.js?version=5.42
    */
    function submitRequest(station_train_code,lishi,starttime,trainno,from_station_telecode,to_station_telecode,arrive_time,from_station_name,to_station_name,from_station_no,to_station_no,ypInfoDetail,mmStr,locationCode) {
    $('#station_train_code').val(station_train_code);
    $('#lishi').val(lishi);
    $('#train_start_time').val(starttime);
    $('#trainno').val(trainno);
    $('#from_station_telecode').val(from_station_telecode);
    $('#to_station_telecode').val(to_station_telecode);
    $('#arrive_time').val(arrive_time);
    $('#from_station_name').val(from_station_name);
    $('#to_station_name').val(to_station_name);
    $('#from_station_no').val(from_station_no);
    $('#to_station_no').val(to_station_no);
    $('#ypInfoDetail').val(ypInfoDetail);
    $('#mmStr').val(mmStr);
    $('#locationCode').val(locationCode);
    // ctx = '/otsweb'
    $('#orderForm').attr("action",
    ctx+"/order/querySingleAction.do?method=submutOrderRequest");
    $('#orderForm').submit();
    }
    第 1 条附言    2013-01-17 17:04:40 +08:00
    由于不清楚如何在v2ex中贴代码, 对丑陋的格局感到非常抱歉, 请大家移至gist fork
    第 2 条附言    2013-01-17 17:15:18 +08:00
    试试直接贴上gist
    <script src="https://gist.github.com/4554460.js"></script>
    8 条回复    1970-01-01 08:00:00 +08:00
    tarsier
        1
    tarsier  
       2013-01-17 17:07:14 +08:00
    ms 可以直接嵌入gist ?
    ufologist
        2
    ufologist  
    OP
       2013-01-17 17:11:16 +08:00
    @tarsier 主题好像不能再编辑了吧? 不知具体如何华丽丽的插入gist
    tarsier
        3
    tarsier  
       2013-01-17 17:14:04 +08:00
    @ufologist 看看这个行不 http://www.v2ex.com/t/1244 我没试过
    ufologist
        4
    ufologist  
    OP
       2013-01-17 17:15:44 +08:00
    试试直接贴上gist
    <script src="https://gist.github.com/4554460.js"></script>
    unstop
        5
    unstop  
       2013-01-17 17:15:48 +08:00
    感谢楼主,楼主为了发这贴掉了不少血吧。

    楼下也给点一下感谢帮楼主回点血呗。
    ufologist
        6
    ufologist  
    OP
       2013-01-17 17:18:23 +08:00
    <script src="http://gist.github.com/4554460.js"></script>
    ufologist
        7
    ufologist  
    OP
       2013-01-17 17:20:04 +08:00
    ufologist
        8
    ufologist  
    OP
       2013-01-17 17:22:29 +08:00
    郁闷了, 如何删掉自己的回复, gist贴出来严重影响页面美观啊...求助@Livid
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4412 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 09:33 PVG 17:33 LAX 01:33 JFK 04:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86