前言
每逢期末出分的时候,我宝一天能进n次查分网站,为的就是看有没有新出的成绩。然而这样子劳民伤财,费时费力(挂vpn+登校园网+查看),于是我试着扒了下网站的源码,参考网上类似的教程写了一段简短的js运行脚本,以方便出分时自动查看。也算是增加一点经验hh
特性
自动定时获取某学期当前最新成绩,可自定义
支持成绩提醒,可自定义
- 每次刷新后提醒(不推荐,仅作测试和debug用)
- 成绩有变动时提醒
提醒方式包括
脚本代码
脚本代码见下,具体使用方法和解析见后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
let timeout = Number(prompt('输入查询成绩的时间间隔(请不要太短,以免被认为是攻击)', '15')); let academicTerm = prompt('输入查询成绩的学期(格式:4位年份+季节,例如:2022夏)', '2022夏'); let whetherShowContinuously = prompt('是否开启持续提示(默认为否,填任意其他内容即为是)(微信提醒时不建议开启)', '否'); let whetherShowExplorerMessage = prompt('是否开启浏览器消息提示(默认为否,填任意其他内容即为是)', '否'); let whetherShowWechatMessage = prompt('是否开启微信提示(需登录息知(https://xz.qqoq.net/#/index)获取key)(默认为是,填任意其他内容即为否)', '是'); let key; if (whetherShowWechatMessage == '是') { key = prompt('输入息知里对应的key'); }
let semesterDic = { '秋': 1, '冬': 2, '春': 3, '夏': 5 }; let academicTermID = (Number(academicTerm.substring(0, 4)) - 1) * 10 + semesterDic[academicTerm.substring(academicTerm.length - 1, academicTerm.length)];
count = 0; current = location.href;
let gradeTable = []; let oldGradeTable = [];
if (timeout > 0) { setTimeout('reload()', 1000 * timeout); } else { location.replace(current); }
function reload() { setTimeout('reload()', 1000 * timeout); count++; console.log(`每${timeout}秒自动刷新,刷新次数:${count}`);
$.ajax({ type: "POST", url: "/StudentPortal/CtrlScoreQuery", data: { academicTermID: academicTermID }, cache: false, success: function (gradeResponse) { oldGradeTable = gradeTable; let gradeHTML = gradeResponse; let placeholder = document.createElement('div'); placeholder.innerHTML = gradeHTML; let gradeTableHTML = placeholder.getElementsByClassName("tbllist")[0]; for (var i = 0, rows = gradeTableHTML.rows.length; i < rows; i++) { for (var j = 0, cells = gradeTableHTML.rows[i].cells.length; j < cells; j++) { if (!gradeTable[i]) { gradeTable[i] = new Array(); } gradeTable[i][j] = gradeTableHTML.rows[i].cells[j].innerHTML.replace(/\s/g, "").replace(/ /g, ""); } } } });
checkInfo(); }
function checkInfo() { if (oldGradeTable.length == 0) { oldGradeTable = gradeTable; } else if (oldGradeTable != gradeTable) { oldGradeTable = gradeTable; notify(); } else { if (whetherShowContinuously != '否') { notify(); } } }
function arr2Str(objarr) { var arrLen = objarr.length; var row = "["; for (var i = 2; i < arrLen; i++) { row += "["; for (var j = 0; j < objarr[i].length; j++) { row += objarr[i][j]; if (j < objarr[i].length - 1) { row += ","; } } row += "]"; if (i < arrLen - 1) { row += ","; } } row += "]"; return row; }
function notify() { let body = arr2Str(gradeTable);
if (whetherShowExplorerMessage != "否") { if (window.Notification && Notification.permission !== "denied") { Notification.requestPermission(function (status) { var n = new Notification(`有成绩更新!`, { body: body }); }); } }
if (whetherShowWechatMessage == '是') { sendWechatMessage(key, "有成绩更新!", body); } }
function sendWechatMessage(key, title, message) { var httpRequest = new XMLHttpRequest(); httpRequest.open('GET', `https://xizhi.qqoq.net/${key}.send?title=${title}&content=${message}`, true); httpRequest.send(); }
|
使用方法
推荐浏览器:Chrome
登录到上海大学教务管理系统(需要校园网或连接VPN(说明))
F12
打开开发者工具,找到Console
控制台,将上文的脚本代码复制粘贴至此,然后enter换行开始运行
输入自定义设置
时间间隔
学期名
默认只在成绩更新时发送通知,这里为演示效果,将持续提醒设为了是
浏览器提示,当你经常使用电脑时,可以借此接收提醒
微信通知(建议开启)
微信提示调用了息知的接口,需登录其网站,获取对应Key
复制粘贴到输入框中
完成后,保持该窗口不关闭,即可自动开始运行
浏览器提醒样式
微信提醒样式(需关注息知公众号)
原理剖析
shu教务系统
仅做技术分享,莫拿来当攻击手段哈~
教务系统的技术栈比较老,还是jQuery+Ajax,样式就用基础的css(我济都用上element UI了~)
登录这一块本来也想做做,但是对html的基础知识还是不够了解,因而作罢。本质上说就是设定表单提交的url,然后对password进行加密,加上username直接传过去,成功就跳转页面。
查分这一块特别简单,抓了一下包发现,网页上面的查询
按钮,对应调用的就是ScoreQuery
函数,该函数发送了一个ajax的post请求,返回的response即为下面成绩一栏的html源码,然后通过指定id,直接把这段html赋给了网页…
Post请求里带的AcademicTermID
,搜索后可发现,即为对应的学期名,并且存在映射关系,如
{ '秋': 1, '冬': 2, '春': 3, '夏': 5 }
微信提醒
微信提醒调用了息知的api接口(之前还看过server酱的接口,然鹅现在看貌似每天只能免费五条)
扫描二维码后,通过get或post请求发送如下内容
1
| https://xizhi.qqoq.net/{key}.send?title=标题&content=内容
|
即可
bug
异步
js与其他语言相比,最大的特点在于异步,例如ajax发送了post请求获得成绩,但是在发送请求的那一刻开始,尽管还没有接收到结果,但是代码已经往下执行了,所以当到checkInfo
的时候,可能并未获取最新的成绩。我修改了一些逻辑,以掩饰这个bug()
参考链接
https://juejin.cn/post/7043325422796439560
https://github.com/panghaibin/shu-web-js