Skip to content

Instantly share code, notes, and snippets.

@Konano
Last active March 21, 2024 00:08
Show Gist options
  • Save Konano/575125a0f8941c2c4ee9c0875c6a151e to your computer and use it in GitHub Desktop.
Save Konano/575125a0f8941c2c4ee9c0875c6a151e to your computer and use it in GitHub Desktop.
半自动化抢 JLPT 考场
var monitorSchool = ["北京语言大学", "北京大学", "北京外国语大学"]; // 填写想要的学校
var speedUp = false; // 加速与否
var notNeedConfirm = true; // 预定前是否需要确认
var defaultName = '北京语言大学';
var defaultID = 3;
var skipKDInfo = false; // 跳过 getKDInfo 直接使用默认值提交预定
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var selectorinputChk = "#chooseaddrForm > table:nth-child(1) > tbody > tr:nth-child(2) > td.inputChk > img";
var selectorvalueChk = "#chooseaddrForm > table:nth-child(1) > tbody > tr:nth-child(2) > td.inputChk > input[type=text]:nth-child(2)";
var chkStatus = 0;
var chkImg = document.querySelector(selectorinputChk);
var chkImgCode = document.querySelector(selectorvalueChk);
var initStatus = 0;
function initChkImg() {
if (initStatus == 0) {
initStatus = 1;
chkImg.height *= 3;
chkImg.width *= 3;
chkImg.addEventListener('load', async function(e) {
if (chkStatus == 1) {
await sleep(200);
if (chkStatus == 1) {
chkStatus = 9;
chkImgCode.value = prompt('验证码');
if (chkImgCode.value != '') {
chkStatus = 0;
} else {
chkStatus = -1;
}
}
}
}, true);
}
}
function getChkimgAjax(c) {
cache.redo = null;
cache.cancel = function() {
if (user.get("step") == "register") {
gotoStep("agreement")
}
}
;
var e = c;
setChangeImgLink(e, false);
c = $(c);
var b = getURL("chkImg.do");
var d = c.getElementsBySelector("input[name='chkImgCode']")[0];
var f = c.getElementsBySelector("[name='chkImg']")[0];
var a = user.get("chkImgFlag");
if (!a) {
a = generateRandomFlag(18);
user.set("chkImgFlag", a)
}
new Ajax.Request(b,{
method: "post",
parameters: "chkImgFlag=" + a,
requestHeaders: {
RequestType: "ajax"
},
onSuccess: function(g) {
var h = g.responseJSON;
if (h == null) {
g.request.options.onFailure();
return
}
if (!h.retVal) {
processError(h.errorNum);
return
}
user.set("chkImgSrc", h.chkImgFilename);
d.value = "";
setChkimg(c);
setChangeImgLink(e, true)
},
onFailure: function(g) {
setChangeImgLink(e, true)
}
})
}
function processError(a) {
var c;
if (cache["getMsg" + a]) {
c = cache["getMsg" + a];
cache["getMsg" + a] = null
}
var b;
if (cache["remainAction" + a]) {
b = cache["remainAction" + a];
cache["remainAction" + a] = null
}
var d;
if (cache["getTickMsg" + a]) {
d = cache["getTickMsg" + a];
cache["getTickMsg" + a] = null
}
if (!c) {
c = function() {
return errorCode[a]
}
}
if (layer) {
layer.setMsg(c(a))
}
console.log('错误代码', a);
if (a == 101 || a == 102 || a == 303 || a == 315 || a == 316 || a == 310) {
if (!b) {
b = function() {
gotoStep("login")
}
}
layer.show();
layer.setTickMsg(1, b, d);
return
}
if (a >= 200 && a <= 206 || a >= 300 && a <= 317) {
if (!b) {
b = function() {
cancel()
}
}
if (a == 313) chkStatus = -9; else chkStatus = -4;
if (layer) {
layer.hide()
}
b();
return
}
if (!b) {
b = dispatch
}
if (layer) {
layer.show();
chkStatus = -3;
cancel();
}
}
function bookseat(c, b, a) {
c = $(c);
var d = c.getElementsBySelector("[name='chkImgCode']")[0];
if (checkIsInValid(checkIsNull, d, function() {
alert("请输入验证码")
})) {
return
}
user.set("bkkd", b);
if (!notNeedConfirm && !confirm("您所选择的考试级别为:" + LevelName[user.get("bkjb")] + ",考试地点为:" + a)) {
return
}
cache.redo = function() {
bookseat(c, b, a)
}
;
cache.cancel = null;
if (user.get("isChangeKD") == 0) {
new Ajax.Request(getURL("book.do"),{
method: "post",
requestHeaders: {
RequestType: "ajax"
},
parameters: serializeUser(["bkjb", "bkkd", "ksid", "ksIdNo", "chkImgFlag", "ksLoginFlag"]) + "&chkImgCode=" + $F(d),
onCreate: function() {
layer.show();
chkStatus = 3;
layer.setTitle("定座");
layer.setMsg("定座请求发送中...");
layer.showLoading()
},
onSuccess: function(e) {
var h = e.responseJSON;
if (h == null) {
e.request.options.onFailure();
return
}
clearChkimgCache();
if (h.retVal == 0) {
cache.remainAction304 = function() {
gotoStep("status")
}
;
function i() {
getChkimg("chooseaddrDiv")
}
cache.remainAction305 = i;
cache.remainAction306 = i;
cache.remainAction313 = i;
processError(h.errorNum);
return
}
var g = getURL("queryBook.do");
var k = serializeUser(["ksid", "ksIdNo", "ksLoginFlag"]);
var j = 10;
var f = function() {
new Ajax.Request(g,{
method: "post",
requestHeaders: {
RequestType: "ajax"
},
parameters: k,
onCreate: function() {
layer.setMsg("定座请求结果查询中...")
},
onSuccess: function(l) {
var m = l.responseJSON;
if (m == null) {
l.request.options.onFailure();
return
}
if (m.retVal == 0) {
cache.getTickMsg310 = function(o, n) {
return ""
}
;
cache.remainAction310 = f;
cache.remainAction304 = function() {
gotoStep("status")
}
;
processError(m.errorNum)
} else {
updateUser(m);
layer.setMsg("预定座位成功");
chkStatus = -2;
layer.setTickMsg(3, dispatch)
}
},
onFailure: function() {
if (--j <= 0) {
cache.getMsg317 = function() {
return "查询错误次数过多"
}
;
processError(317)
} else {
cache.getTickMsg316 = function(m, l) {
return (l - m) + "秒后重试..."
}
;
cache.remainAction316 = f;
j = 10;
processError(316)
}
}
})
};
f()
},
onFailure: function() {
processError(100)
}
})
} else {
new Ajax.Request(getURL("changebook.do"),{
method: "post",
requestHeaders: {
RequestType: "ajax"
},
parameters: serializeUser(["bkjb", "bkkd", "ksid", "ksIdNo", "chkImgFlag", "ksLoginFlag"]) + "&chkImgCode=" + $F(d),
onCreate: function() {
layer.show();
layer.setTitle("更改考点");
layer.setMsg("更改考点请求发送中...");
layer.showLoading()
},
onSuccess: function(e) {
var f = e.responseJSON;
if (f == null) {
e.request.options.onFailure();
return
}
clearChkimgCache();
if (f.retVal == 0) {
processError(f.errorNum);
return
}
layer.setMsg("更改考点成功");
chkStatus = -2;
layer.setTickMsg(3, dispatch)
},
onFailure: function() {
processError(100)
}
})
}
}
var availableSchool = [];
function getKDInfo() {
cache.redo = getKDInfo;
cache.cancel = null;
new Ajax.Request("chooseAddr.do?bkjb=" + user.get("bkjb"),{
method: "get",
requestHeaders: {
RequestType: "ajax"
},
onCreate: function() {
layer.show();
layer.setTitle("选择考点");
layer.setMsg("页面载入中");
layer.showLoading()
},
onSuccess: function(originalRequest) {
var jsonObj = eval(originalRequest.responseText);
if (jsonObj == null) {
originalRequest.request.options.onFailure();
return
}
availableSchool = jsonObj.filter(x => monitorSchool.includes(x.mc) && x.vacancy != 0);
layer.hide();
},
onFailure: function(originalRequest) {
processError(100)
}
})
}
var schoolName = '北京语言大学';
var schoolID = 3;
async function main() {
initChkImg()
chkStatus = 0;
while (true) {
// 验证码
chkStatus = 1;
getChkimgAjax('chooseaddrDiv');
while (chkStatus == 1 || chkStatus == 9) { await sleep(10); }
console.log('验证码', chkStatus);
if (chkStatus == -1) break;
// 监控是否可预订
while (availableSchool.length == 0 && skipKDInfo == false) {
chkStatus = 0;
getKDInfo();
await sleep(100);
while (layer.visible() && chkStatus == 0) { await sleep(10); }
if (speedUp) {
await sleep(50);
} else {
await sleep(1000);
}
}
if (skipKDInfo) {
schoolID = defaultID;
schoolName = defaultName;
} else {
console.log('可预订学校', availableSchool);
schoolID = availableSchool[0].id;
schoolName = availableSchool[0].mc;
}
// 预定
chkStatus = 2;
bookseat('chooseaddrForm',schoolID,schoolName);
while (chkStatus == 2) { await sleep(10); }
while (layer.visible() && chkStatus == 3) { await sleep(10); }
console.log('预定', chkStatus);
if (chkStatus == -2) break;
if (chkStatus == -3) break;
if (chkStatus == -4) continue;
if (chkStatus == -9) {
availableSchool = []; // 该考场已无座位
continue;
}
}
}
var selectortitle = "#kdTable > tbody > tr:nth-child(1) > th"
var title = document.querySelector(selectortitle);
var button = document.createElement("input");
button.setAttribute("type", "button");
button.setAttribute("value", "捡漏");
button.setAttribute("onclick", "main()");
title.appendChild(button);
// main();
@Konano
Copy link
Author

Konano commented Mar 23, 2021

使用方法:在网页显示「考场列表」的时候,复制代码直接丢进 Chrome 的控制台(Console)

如果想退出直接刷新网页即可。
验证码还是得手动输入,无视大小写。
修改考场的话请手动修改代码前两行。

@Konano
Copy link
Author

Konano commented Sep 7, 2021

使用前要在页面内随便划一段话……

UPD: 好像现在又不用了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment