Skip to content

Instantly share code, notes, and snippets.

@fireball2018
Created January 8, 2012 10:41
Show Gist options
  • Save fireball2018/1577961 to your computer and use it in GitHub Desktop.
Save fireball2018/1577961 to your computer and use it in GitHub Desktop.
A javascript snippet to help you booking train tickets at 12306.com
/*
12306 Auto Query => A javascript snippet to help you book tickets online.
12306 Booking Assistant
Copyright (C) 2011 Hidden
12306 Auto Query => A javascript snippet to help you book tickets online.
Copyright (C) 2011 Jingqin Lynn
12306 Auto Login => A javascript snippet to help you auto login 12306.com.
Copyright (C) 2011 Kevintop
Includes jQuery
Copyright 2011, John Resig
Dual licensed under the MIT or GPL Version 2 licenses.
http://jquery.org/license
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// rewrite https://github.com/zzdhidden/12306/
// ==UserScript==
// @name 12306 Assistant Plus
// @author [email protected]
// @namespace https://github.com/jiedan
// @description A javascript snippet to help you booking train tickets at 12306.com
// @include *://dynamic.12306.cn/otsweb/loginAction.do*
// @include *://dynamic.12306.cn/otsweb/order/querySingleAction.do*
// @include *://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do*
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
// ==/UserScript==
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);";
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);
});
}
document.head.appendChild(script);
} else {
callback(jQuery);
}
}
withjQuery(function($){
$(document).click(function() {
if( window.webkitNotifications && window.webkitNotifications.checkPermission() != 0) {
window.webkitNotifications.requestPermission();
}
});
var notify = function(str, timeout) {
if( window.webkitNotifications && window.webkitNotifications.checkPermission() == 0) {
var notification = webkitNotifications.createNotification(
null, // icon url - can be relative
'订票', // notification title
str
);
notification.show();
if ( timeout ) {
setTimeout(function() {
notification.cancel();
}, timeout);
}
} else {
alert( str );
}
}
if( window.location.href.indexOf("querySingleAction.do") != -1 ) {
//query
var isTicketAvailable = false;
//The table for displaying tickets
var tbl = $(".obj")[0];
tbl.addEventListener("DOMNodeInserted", function() {
if(checkTickets(event.target))
{
isTicketAvailable = true;
highLightRow(event.target);
}
tbl.firstAppend=false;
}, true);
//Trigger the button
var doQuery = function() {
displayQueryTimes(queryTimes++);
tbl.firstAppend = true;
g.firstRemove = true;
document.getElementById(isStudentTicket ? "stu_submitQuery" : "submitQuery").click();
}
var checkTickets = function(row) {
var hasTicket = false;
var canBook = true;
$("td input[type=button]", row).each(function(i, e) {
if(e.classList.contains("yuding_x")) {
canBook = false;
}
});
if(!canBook) return false;
$("td", row).each(function(i, e) {
if(ticketType[i-1]) {
var info = e.innerText.trim();
if(info != "--" && info != "无") {
hasTicket = true;
highLightCell(e);
}
}
});
return hasTicket;
}
//The box into which the message is inserted.
var g = document.getElementById("gridbox");
//When the message is removed, the query should be completed.
g.addEventListener("DOMNodeRemoved", function() {
if(g.firstRemove) {
g.firstRemove = false;
if (isTicketAvailable) {
if (isAutoQueryEnabled)
document.getElementById("refreshButton").click();
onticketAvailable(); //report
}
else {
//wait for the button to become valid
}
}
}, true);
//hack into the validQueryButton function to detect query
var _validQueryButton = validQueryButton;
validQueryButton = function() {
_validQueryButton();
if(isAutoQueryEnabled) doQuery();
}
var queryTimes = 0; //counter
var isAutoQueryEnabled = false; //enable flag
//please DIY:
var audio = null;
var onticketAvailable = function() {
notify("可以订票了!");
if(window.Audio) {
if(!audio) {
audio = new Audio("http://www.w3school.com.cn/i/song.ogg");
audio.loop = true;
}
audio.play();
}
}
var highLightRow = function(row) {
$(row).css("background-color", "red");
}
var highLightCell = function(cell) {
$(cell).css("background-color", "blue");
}
var displayQueryTimes = function(n) {
document.getElementById("refreshTimes").innerText = n;
};
var isStudentTicket = false;
//Control panel UI
$("<div>请先选择好出发地,目的地,和出发时间。&nbsp;&nbsp;&nbsp;</div>").append(
$("<input/>").attr("type", "checkBox").change(function(){
isStudentTicket = this.checked;
})
).append(
$("<span/>").html("学生票&nbsp;&nbsp;")
).append(
$("<button 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);'/>").attr("id", "refreshButton").html("自动刷票").click(function() {
if(!isAutoQueryEnabled) {
isTicketAvailable = false;
if(audio && !audio.paused) audio.pause();
isAutoQueryEnabled = true;
doQuery();
this.innerText="停止刷票";
}
else {
isAutoQueryEnabled = false;
this.innerText="开始刷票";
}
})
).append(
$("<span>").html("&nbsp;&nbsp;尝试次数:").append(
$("<span/>").attr("id", "refreshTimes").text("0")
)
).insertBefore($(".cx_title_w:first"));
//Ticket type selector & UI
var ticketType = new Array();
$(".hdr tr:eq(2) td").each(function(i,e) {
ticketType.push(false);
if(i<3) return;
ticketType[i] = true;
var c = $("<input/>").attr("type", "checkBox").attr("checked", "true");
c[0].ticketTypeId = i;
c.change(function() {
ticketType[this.ticketTypeId] = this.checked;
}).appendTo(e);
});
}
else if( window.location.href.indexOf("loginAction.do") != -1 ) {
//login
var url = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login";
var queryurl = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=init";
function submitForm(){
var submitUrl = url;
$.ajax({
type: "POST",
url: submitUrl,
data: {
"loginUser.user_name": $("#UserName").val()
, "user.password": $("#password").val()
, "randCode": $("#randCode").val()
},
timeout: 30000,
//cache: false,
//async: false,
success: function(msg){
if (msg.indexOf('请输入正确的验证码') > -1) {
alert('请输入正确的验证码!');
};
if (msg.indexOf('当前访问用户过多') > -1) {
reLogin();
}
else {
notify('登录成功,开始查询车票吧!');
location.replace(queryurl);
};
},
error: function(msg){
reLogin();
},
beforeSend: function(XHR){
//alert("Data Saved: " + XHR);
}
});
}
var count = 1;
function reLogin(){
count ++;
$('#refreshButton').html("("+count+")次登录中...");
setTimeout(submitForm, 2000);
}
//初始化
$("#subLink").after($("<a href='#' 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);'/>").attr("id", "refreshButton").html("自动登录").click(function() {
count = 1;
$(this).html("(1)次登录中...");
notify('开始尝试登录,请耐心等待!', 4000);
submitForm();
return false;
}));
$(".enter_left,.enter_right").css("height", "383px");
$(".enter_from").append("<div style='color:red'>如果使用自动登录功能,请输入用户名、密码及验证码后,点击自动登录,系统会尝试登录,直至成功!</div>");
} else if( window.location.href.indexOf("confirmPassengerAction.do") != -1 ) {
var num = $("#showPassengerFilter ._checkbox_class").length;
if (num > 1){
if( num > 5) num = 5;
for(var i = 1; i <= num; i++){
$(".add_ticket_passenger").click();
}
}
$("#showPassengerFilter ._checkbox_class").click();
$("<span id='custom_buttons'></span>").append(
$("<button 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);'/>").attr("id", "submitOrder").html("提交订单").click(function() {
var formId = "confirmPassenger";
if(!submit_form_check(formId)) {
return false;
}
var ticket_info = getTicketInfo();
var passenger_info = getPassengerInfo();
failfunc();
})
).insertAfter("#img_rrand_code");
$("input[name=randCode]").focus();
var userInfoUrl = 'https://dynamic.12306.cn/otsweb/sysuser/user_info.jsp';
//var userInfoUrl = 'https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y';
var count = 1;
var tokenSplitStr = '<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="';
function submitOrderForm(){
jQuery.ajax({
url: $("#confirmPassenger").attr('action'),
data: $('#confirmPassenger').serialize(),
type: "POST",
timeout: 30000,
success: function(msg)
{
if(msg.indexOf(tokenSplitStr) > -1){
$("input[name='org.apache.struts.taglib.html.TOKEN']").val(msg.split(tokenSplitStr)[1].split('">')[0]);
}
if (msg.indexOf('输入的验证码不正确') > -1) {
alert('请输入正确的验证码!');
} else if (msg.indexOf('用户过多') > -1) {
reSubmitOrderForm();
}else if (msg.indexOf('确认客票的状态后再尝试后续操作') > -1) {
//alert('呃。。。可能没票了,赶紧返回选别的票吧,否则将继续为你尝试!');
reSubmitOrderForm();
}else if(msg.indexOf('没有足够的票') > -1){
//alert('系统说,没有足够的票了,您还是换个车次吧。。。');
reSubmitOrderForm();
}else if(msg.indexOf('席位已经锁定') > -1){
$('#refreshButton').html("车票预订成功,恭喜!");
location.replace(userInfoUrl);
}else if(msg.indexOf('请不要重复提交') > -1){
//alert('重复提交,继续重试!!!');
reSubmitOrderForm();
}else if(msg.indexOf('席别不能为空') > -1){
alert('席别不能为空');
}else if(msg.indexOf('取消次数过多') > -1){
alert('您取消次数过多,系统不受理,请明天再买吧!!!');
}else if(msg.indexOf('验证码 必须输入') > -1){
alert('验证码 必须输入');
}else{
console.log(msg);
alert('出错了。。。。 啥错? 我也不知道。。。。。');
};
},
error: function(msg){
reSubmitOrderForm();
}
});
};
function reSubmitOrderForm(){
count ++;
$('#refreshButton').html("("+count+")次自动提交中...");
setTimeout(submitOrderForm, 500);
}
//初始化
if($("#refreshButton").size()<1){
$("#custom_buttons").append($("<a href='#' 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);'/>").attr("id", "refreshButton").html("自动提交订单").click(function() {
alert('开始自动提交订单,请点确定后耐心等待!');
count = 1;
$(this).html("(1)次自动提交中...");
if(window.submit_form_check && !submit_form_check("confirmPassenger") ) {
return;
}
submitOrderForm();
return false;
}));
}
}
}, true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment