如何为「四川大学综合教务系统」增加「一键评教」功能

【2020 年 4 月 8 日更新】这是一篇我在 2018 年 6 月写的博文,讲述了如何快速评教的技术细节。但我发现很多人从百度而来,只是为了找一个快速评教的方法的,不太想看实现的技术细节……如果您有这样的需求,我已经制作了一个脚本叫做 四川大学综合教务系统助手,一直在稳定更新,从旧版教务系统一路适配到新版教务系统的最新版本,其中有一个功能就是快速评教。您可以点这里使用:https://zhaoji.wang/sichuan-university-urp-assistant/


生活中总有些事情是绕不开的,比如明远湖上的长桥与概率统计的小测,比如学校的评教系统:

我不知道为什么「教学评估」和江安西园二餐厅的二楼天花板一样是绿色,也许是为了告诉大家要坚强,或者在暗示别的什么,但当我每次面对着三十个待评价的老师/助教,却只有一两个想专门写两句评语时,我都感觉自己坚强不起来。

大一上学期时,有人在群里共享了这个,以及类似的一系列自动评教软件,只需要输入教务处的账号和密码就可以使用:

我用了后感觉还行,但后来假期邱哥说他看到有人统计上课数据信息之类的,统计时的数据来源就是这类软件截留下的信息。这类软件很多,我不知道邱哥指的是哪一款,但这种独立的评教软件,不管是一个 exe 桌面程序,还是一个网页,还是一个微信小程序,本质上都是「代理登录」,也就是说,这个程序拿着我的学号和密码去登陆教务处帮我完成评教工作,至于程序干了什么事,我的账号和密码在教务处之外的服务器上存放着有没有风险,这都不得而知。

于是作为一个程序猿,我决定自己写一个一键评教工具。

这个工具不是独立的,而是直接集成在教务系统的网页上,相当于为教务系统添加功能,因此没有什么「代理登录」之类的隐忧。我觉得程序在社会主义初级阶段应该从简,做一个这样的按钮放在评教页面,然后按钮旁边直接显示文字提示就可以了:

现在这个脚本已经写好了,我把它和我之前写的修复脚本合并在了一起,制作了一个全新的脚本叫做「四川大学综合教务系统助手」,可以通过 Userscript 与 书签工具栏按钮 两种方式调用,需要使用的可以点这里:https://zhaoji.wang/sichuan-university-urp-assistant/

下面我记述一下制作这个脚本的过程。

要评教老师,首先要让程序明白被评教老师的信息,这很简单,按照经验,这种年代久远的系统信息肯定都在 html 文件里,我们用审查元素看一下便知道。

让我们来看看这个小图片上有什么:

可以看到,老师与课程的信息都保存在 name 属性中,这是一种经典的保存信息做法。那我们直接顺藤摸瓜,看一看鼠标点击这个按钮之后发生了什么。注意,这里因为我已经评教完了,所以 onclick 对应的方法变成了 check(),如果这里是未评价状态的话,对应的方法应该是 evaluate()。

有人可能会想,为什么这里一开始就知道要看这个小图标的代码是什么呢?因为我们做一键评教,实际上是一个让计算机代替人类重复工作的过程,那么,我们人类干了什么,就得让计算机模拟干什么。我们人评教时需要点这里,自然需要看看点这里的过程中有什么代码被执行了,才好让计算机模拟相同的操作。

这个函数完整的代码如下:

看起来很吓唬人,实际上就是把刚才那个 name 属性的字符串拆开了,然后给 WjList 表单里的几个 input 标签的 value 赋值,最后将这个表单提交,发送数据到服务端。

网络请求为:

带的参数为:

一个标准的表单提交,提交之后这个 mainFrame 框架将跳转到/jxpgXsAction.do,显示的内容就是评教的选项:

没什么特别的,那么,我们直接模拟这个网络请求就可以。

其实一开始我写代码时,把这一步跳过了,直接发送了后面评教的网络请求,然后一直报错,后来我才发现前面这一步请求不能少=-=

我们需要获取列表里的每一个小图标包含的老师+课程数据,然后根据这条数据的信息发送请求。注意,这里用 img 的 title 过滤掉了已经评教过的老师,只保留尚未评教的老师数据。至于为什么要按照「评估」来区分,这个是用审查元素观察出来的:

这时候得到的就是刚才看到的一条条很长的 name 字符串,下面需要解析字符串的内容:

教务系统的分割方法比较原始,我们现在直接用 split 即可:

然后模拟发请求即可,这里我直接用 fetch 发了,与时俱进,不用什么 XMLHTTPRequest 了:

下面开始第二部分,分析具体老师的评价页面。

当然,因为我这里已经评教过了,所以显示的是评教之后的界面了,截不到原来的图了。原来的那个评教页面上,大概选项是这样组织的,因为这是评教之后的页面,所以它都已经给注释掉了:

input radio 标签的 value 值决定了这一项评分的高低,非常同意对应的是「10_1」,然后其他的选项依次递减,最低是非常不同意,对应的是「10_0.2」

这里的 name 很有意思,是一个 10 位的数字,每个问题都有自己的 name。根据我的测试,研究生助教评价对应的是 28-33,学生评教(课堂教学)对应的是 36-42,学生评教(实验教学)对应的是 82-88,学生评教(实践教学)对应的是 89-95,学生评教(体育教学)对应的是 96-102,在模拟发送请求时前补零补足十位即可。

主观评价部分对应的文本域的 name 叫做 zgpj,汉语拼音缩写,让我想起了我初中的时候。

然后随便提交一个看看请求的参数,确定没啥意外的信息就可以模拟请求了。因为我已经评教过了,截不到那个图了=-=这里就不放图了。

首先处理一下不同类型的评教问卷的题目对应编号,编号是之前一个一个手动用审查元素看出来的,看出来记下就好了。

然后构建请求的 body,首先需要把问卷、老师、科目的编号填上。然后是每一道题目的得分,这里都是非常满意对应的「10_1」,可能表示每道题目都得满分 1 分吧。格式就是表单 POST 请求的 x-www-form-urlencoded 格式。

然后加上评论:

评论当然不能千篇一律,所以需要一个随机评论的方法。然后这里有个坑,请求里的评论文字是以着 gbk 方式编码的,但 JavaScript 根本不支持对文字以 gbk 格式编码,只支持对文字按照 utf-8 格式编码。如果要引入外部库,我觉得对于这个小程序而言有点多余了。所以我就随便编了六条好评,然后提前用 Java 转成了 gbk 编码,写到了 getComment() 方法中:

好的,现在万事俱备只欠东风,可以发请求了:

然后判断一下评教的结果,在网页上给个反馈。之后等待一定时间再评价下一位老师,我在脚本里设置的 interval 是 500 毫秒。其实不设置等待时间也可以,但感觉那样教务系统服务器的压力会比较大,用的人多了说不定会崩溃掉,所以还是给它减减负吧:

然后,脚本跑得很成功,一口气评价一页老师不费劲:

这个评教脚本写好之后,我把它和我之前写的修复教务系统在现代化浏览器下无法正常使用的脚本合并在了一起,制作了一个全新的脚本叫做「四川大学综合教务系统助手」,可以通过 Userscript 与 书签工具栏按钮 两种方式调用,需要使用的可以点这里:https://zhaoji.wang/sichuan-university-urp-assistant/

本文中的代码多为节选,完整的代码,也就是上段提到的那个脚本,我已经开源到了码云(Gitee)这个国内的公共 git 仓库上。地址为:https://gitee.com/zhaoji/scu-urp-assistant,有需要的同学可以查阅,我们相互交流。有对教务处功能改进的脑洞的同学,也可以告诉我,我会在业余时间继续完善这个脚本。

如何为「四川大学综合教务系统」增加「一键评教」功能》有3个想法

  1. Pingback引用通告: 如何为新版的「四川大学综合教务系统」增加「一键评教」功能 | 一个兆基

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注