zoukankan      html  css  js  c++  java
  • 12306与抢票插件初识

    序. 无数巨人的肩膀

    12306购票浅显研究

    http://xiaowa.org/modules.php?link=read_article&id=129 .

    基于HTTPS协议的12306抢票软件设计与实现--相关接口以及数据格式

    http://m.blog.csdn.net/blog/MINEZHANGHAO/18769159 .

    解析12306订票流程

    http://blog.csdn.net/lzqwebsoft/article/details/18674635 .

    玩转新版12306之抢票篇 

    http://blog.csdn.net/yaerfeng/article/details/18013415 .

    根据大牛们对12306网站的分析,我模仿去年的插件开源代码进行重写,以适应现在新版12306网站。

    本文为阶段性成果记录,有很多不足,敬请大家提示和赐教。

     

    0.写js脚本要考虑的

    我们脚本中写的变量或者元素可能与页面发生重复,需要保护本地变量不被外部变量污染

    (function($j) {
        // your code
    })(jQuery)

    考虑页面如果突然不支持jQuery我们的脚本就不能运行了,需要检测并加载我们的脚本同时,保留原来$的方法

    原理知道了,下面这个为高手写成的兼容jQuery框架,我们只需将callback函数作为参数写好就行。

    withjQuery(function($, window) {}, true); 在框架内就可以不与外界冲突的使用$

    另外,用jQuery加载脚本jQuery.getScript("/js/script.js").done(function() {/* Success CallBack */}).fail(function(){/*Fail CallBack*/});

    function withjQuery(callback, safe) {
        if ( typeof (jQuery) == "undefined") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
    
            if (safe) {
                var cb = document.createElement("script");
                cb.type = "text/javascript";
                cb.textContent = "jQuery.noConflict();(" + callback.toString() + ")(jQuery, window);";
                script.addEventListener('load', function() {
                    document.head.appendChild(cb);
                });
            } else {
                var dollar = undefined;
                if ( typeof ($) != "undefined")
                    dollar = $;
                script.addEventListener('load', function() {
                    jQuery.noConflict();
                    $ = dollar;
                    callback(jQuery, window);
                });
            }
            document.head.appendChild(script);
        } else {
            setTimeout(function() {
                //Firefox supports
                callback(jQuery, typeof unsafeWindow === "undefined" ? window : unsafeWindow);
            }, 30);
        }
    }

    1.查票页面优化

    对查询票的页面进行注入,获得用户更适合抢票的体验。

    var ticketType = new Array();
            $("#float th").each(function(i, e) {
                ticketType.push(false);
                if (i > 3 && i < 15) {
                    ticketType[i] = true;
                    var that = $("<input/>").attr("type", "checkBox").attr("checked", true);
                    that.index = i;
                    that.change(function() {// 绑定change事件
                        ticketType[that.index] = this.checked;
                    });
                    $(e).append(that);
                }
            });
    function notify(str, timeout, skipAlert) {// Webkit 桌面通知
                if (window.webkitNotifications && window.webkitNotifications.checkPermission() == 0) {
                    var notification = webkitNotifications.createNotification("http://www.12306.cn/mormhweb/images/favicon.ico", '抢票消息', str);
                    notification.show();
                    if (timeout) {
                        setTimeout(function() {
                            notification.cancel();
                        }, timeout)
                    }
                } else {
                    if (window.webkitNotifications && window.webkitNotifications.checkPermission() != 0) {
                        window.webkitNotifications.requestPermission();
                    }
                    if (!skipAlert) {
                        alert(str);
                    }
                }
            }
    function checkTickets(row) {
                var v1 = $special.val();
                if (v1 != '') {
                    var v2 = $.trim($(row).find(".train a").text());
                    if (v1.indexOf(v2) == -1)
                        return false;
                    if ($(row).find(".no-br a").length == 0) {
                        return false;
                    }
                }
                var cnt = 0;
                $(row).find("td").each(function(i, e) {
                    if (i > 0 && i < 12 && ticketType[i + 3]) {
                        var info = $.trim($(e).text());
                        if (info != "--" && info != "无") {
                            $(this).css("background-color", "#2CC03E");
                            cnt++;
                        }
                    }
                });
                if (cnt && Block) {
                    $(row).find(".no-br a").click();
                    $.post("https://kyfw.12306.cn/otn/confirmPassenger/initDc", {
                        "_json_att" : ""
                    }, function(data) {
                        console.log(data);
                        var str = $.trim(data.match(/globalRepeatSubmitToken.+/));
                        str = str.substr(str.indexOf("= ")).match(/[a-zA-Z0-9]+/);
                        if (str != "")
                            SubmitToken = str;
                    });
                    setTimeout(function() {
                        var $t = $("#defaultwarningAlert_id");
                        if ($t.length) {
                            $t.remove();
                            return false;
                        }
                        $t = $(".dhtmlx_wins_body_outer");
                        if ($t.length) {
                            setTimeout(function() {
                                $t = $t.find('#loginForm');
                                $t.find("input").eq(0).val('401334029@qq.com');
                                $t.find("input").eq(1).val('sks_168168');
                                $('#randCode').keyup(function(e) {
                                    var str = $.trim(e.target.value);
                                    if (str.length == 4)
                                        $t.find("#loginSubAsyn").get(0).click();
                                });
                            }, 1000);
                        }
                    }, 100);
                }
                return cnt;
            }

    2.用户登录优化

    从这里开始就涉及复杂的信息跟踪,我这里仅实现简单的POST登录跳转功能。

    这里还需要用户来输入验证码,这里补充一下JS产生验证码的一种方法: Math.random().toString(16).substr(4,4); 随机一个小数转成16进制后取4到8地址的字符。

    function submitForm() {
                $.ajax({
                    type : "POST",
                    url : "https://kyfw.12306.cn/otn/login/loginAysnSuggest",
                    data : {
                        "loginUserDTO.user_name" : $("#username").val(),
                        "userDTO.password" : $("#password").val(),
                        "randCode" : $("#randCode").val()
                    },
                    beforeSend : function(xhr) {
                        try {
                            xhr.setRequestHeader('X-Requested-With', {
                                toString : function() {
                                    return '';
                                }
                            });
                            xhr.setRequestHeader('Cache-Control', 'max-age=0');
                            xhr.setRequestHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');
                        } catch(e) {
                        };
                    },
                    timeout : 30000,
                    success : function(msg) {
                        // for( var key in msg)
                        // alert(msg[key]);
                        if (msg['data'].loginCheck != 'Y') {
                            alert('请输入正确登录信息');
                            reLogin();
                        } else {
                            alert('登录成功,开始查询车票吧!');
                            window.location.replace(queryurl);
                        }
                    },
                    error : function(msg) {
                        reLogin();
                    }
                });
            }

    3.针对订票过程优化

    给url添加一个timeStamp来避免浏览器缓存得不到正确数据。

    setTimeout(function() {
                if (!$("input.check:checked").length) {
                    $("input.check:first").click();
                }
                $.post("https://kyfw.12306.cn/otn/confirmPassenger/initDc", {
                    "_json_att" : ""
                }, function(data) {
                    var str = $.trim(data.match(/globalRepeatSubmitToken.+/));
                    str = str.substr(str.indexOf("= ")).match(/[a-zA-Z0-9]+/);
                    if (str != "")
                        SubmitToken = str;
                });
                $("#randCode").off('keyup');
                $("#randCode").focus().keyup(function(e) {
                    var str = $.trim(e.target.value);
                    if (str.length == 4) {
                        $.post("https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn", {
                            "randCode" : $("#randCode").val(),
                            "rand" : "randp"
                        }, function(data) {
                            if (data.data == "N") {
                                $(".i-re").click();
                            } else {
                                submitForm();
                                return;
                            }
                        });
                    }
                });
    
                var userInfoUrl = "https://kyfw.12306.cn/otn/queryOrder/initNoComplete";
    
                var count = 1, freq = 1000, doing = false, timer, $msg = $("<div style='padding-left:470px;'></div>");
    
                function submitForm() {
                    timer = null;
                    var info;
    
                    $.post("https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs", {
                        "REPEAT_SUBMIT_TOKEN" : SubmitToken,
                        "_json_att" : ""
                    }, function(data) {
    
                        info = eval(data.data.normal_passengers)[0];
    
                        $.ajax({
                            url : "https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo",
                            data : {
                                'cancel_flag' : '2',
                                'bed_level_order_num' : '000000000000000000000000000000',
                                'REPEAT_SUBMIT_TOKEN' : SubmitToken,
                                "randCode" : $("#randCode").val(),
                                'passengerTicketStr' : '3,0,' + '1,' + info.passenger_name + ',1,' + info.passenger_id_no + ',' + info.mobile_no + ',N',
                                'oldPassengerStr' : info.passenger_name + ',1,' + info.passenger_id_no + ',' + info.mobile_no + info.passenger_type + '_',
                                'tour_flag' : 'dc'
                            },
                            beforeSend : function(xhr) {
                                try {
                                    xhr.setRequestHeader('X-Requested-With', {
                                        toString : function() {
                                            return '';
                                        }
                                    });
                                    xhr.setRequestHeader('Cache-Control', 'max-age=0');
                                    xhr.setRequestHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');
                                } catch(e) {
                                };
                            },
                            type : "POST",
                            timeout : 30000,
                            success : function(data) {
                                if (data.data.submitStatus) {
                                    $.post("https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue", {
                                        'REPEAT_SUBMIT_TOKEN' : SubmitToken,
                                        //"leftTicketStr" : "1015653007404405002630279503121015650165",
                                        'purpose_codes' : '00',
                                        'passengerTicketStr' : '3,0,' + '1,' + info.passenger_name + ',1,' + info.passenger_id_no + ',' + info.mobile_no + ',N',
                                        'oldPassengerStr' : info.passenger_name + ',1,' + info.passenger_id_no + ',' + info.mobile_no + info.passenger_type + '_',
                                    }, function(msg) {
                                        alert(msg.data.submitStatus);
                                        if (msg.data.submitStatus) {
                                            var audio;
                                            if (window.Audio) {
                                                audio = new Audio("http://www.w3school.com.cn/i/song.ogg");
                                                audio.loop = true;
                                                audio.play();
                                            }
                                            setTimeout(function() {
                                                if (confirm("车票预订成,去付款?")) {
                                                    window.location.replace(userInfoUrl);
                                                } else {
                                                    if (audio && !audio.paused)
                                                        audio.pause();
                                                }
                                            }, 100);
                                        } else {
                                            stop(msg.data.errMsg || '未知错误');
                                        }
                                    })
                                } else {
                                    var reTryMessage = ['用户过多', '验证码', '请不要重复提交', '没有足够的票!', '车次不开行'];
                                    for (var i = 0; i < reTryMessage.length; i++) {
                                        if (data.data.errMsg.indexOf(reTryMessage[i]) != -1) {
                                            reSubmitForm(reTryMessage[i]);
                                            return;
                                        }
                                    };
                                    stop(data.data.errMsg || '未知错误');
                                }
                            },
                            error : function(msg) {
                                reSubmitForm("网络错误");
                            }
                        });
                    })
                };
                function reSubmitForm(msg) {
                    if (!doing)
                        return;
                    count++;
                    $msg.html("(" + count + ")次自动提交中... " + (msg || ""));
                    timer = setTimeout(submitForm, freq || 50);
                }
    
                function stop(msg) {
                    doing = false;
                    $msg.html("(" + count + ")次 已停止");
                    $('#refreshButton').html("自动提交订单");
                    timer && clearTimeout(timer);
                    if (msg != '')
                        alert(msg);
                }
    
                if ($("#refreshButton").size() < 1) {
    
                    $(".lay-btn").append($("<a style='padding: 5px 10px; background: #2CC03E;border-color: #259A33;border-right-color: #2CC03E;border-bottom-color:#2CC03E;color: white;border-radius: 5px;text-shadow: -1px -1px 0 rgba(0, 0, 0, 0.2);'></a>").attr("id", "refreshButton").html("自动提交订单").click(function() {
                        //alert('开始自动提交订单,请点确定后耐心等待!');
                        if (this.innerHTML.indexOf("自动提交订单") == -1) {
                            doing = false;
                            stop();
                        } else {
                            doing = true;
                            this.innerHTML = "停止自动提交";
                            reSubmitForm();
                        }
                        return false;
                    }));
                    $(".lay-btn").append("自动提交频率:").append($("<select id='freq'><option value='50' >频繁</option><option value='500' selected='' >正常</option><option value='2000' >缓慢</option></select>").change(function() {
                        freq = parseInt($(this).val());
                    })).append($msg);
                }
            }, 500);
  • 相关阅读:
    Android ADB批处理脚本
    【转载】SecureCRT配色推荐和永久设置
    【转载】Ubuntu中Source Insight的使用
    Ubuntu美化操作
    【转】数据线上的串联小电阻(图)
    VMware下利用ubuntu13.04建立嵌入式开发环境之三
    VMware下利用ubuntu13.04建立嵌入式开发环境之二
    VMware下利用ubuntu13.04建立嵌入式开发环境之一
    ubuntu 13.04 telnet 详细配置
    candence 知识积累4
  • 原文地址:https://www.cnblogs.com/updateofsimon/p/3538078.html
Copyright © 2011-2022 走看看