适用于山传教务系统的自动评教脚本——介绍及原理剖析

作者 by Doubt-Fact /

评教系统与问题

众所周知,学生在使用山传新教务系统查询成绩之前,需要先完成学生评价,即对每一个老师进行打分、评价,也就是所谓的“评教”。这一操作每个老师都要进行一遍,重复操作不说,要填的项目还很繁琐,不仅要给面授课的老师评价,甚至对部分在网上公共平台学习的公选课程也要进行评价,很不合理。
那有没有办法简化这一步骤呢?

分析与解决

油猴

这里先提出一个工具——油猴(Tampermonkey),油猴的本质是浏览器插件,可以运行用户添加的脚本,其原理是对某网站专用JavaScript代码,对网页内容做操作。
正如前面所说,该系统的主要问题是大量的重复操作,那我们完全可以尝试使用脚本模拟人的操作,快速输入内容,最后人工或者自动提交即可。

分析网页

(只有文字,没图,撰文前作者评教提交了,hhh)
(这里应该有《大笑江湖》里没图就不学的表情包,但作者懒得找了,真正做到没图,hhh)

登录新教务系统后,进入学生评价系统,我们就可以看到给老师打分评价的页面了。我们可以看到,需要人填的地方主要是几个部分:

1.输入分数的部分,在这里,需要输入0-100分的评分;

2.输入对老师优缺点、意见的地方,这里是输入的文字;

3.输入对老师评语的部分,这里也是输入文字。
(假装有示意图)
但是,这些是“人”看到并理解的内容,计算机并不能理解其意思,也不能给出对应的操作。我们要用计算机能理解的方式重新分析网页。

这时,我们可以按下键盘上的F12键,或者右键要输入的文本框,点击检查,点击后我们会看到浏览器上出现了一个检查器,显示出当前网页的代码,我们一步步精确到输入框(页面上会高亮显示我们选择到的部分),看看它有什么不同?
很快啊,我们就能发现,这三个部分可以分为两个大类,分别使用了不同的“标签”,也就是不同的控件实现。一类是输入评分的部分,这些代码的内容使用了<input>标签,也就是“表单”输入;另一类是输入文字评语的部分,使用了<textarea>标签,也就是一个多行的文本输入控件。
继续对比,我们就能看到,出了标签外,他们还被定义了不同的class,这就让我们可以进一步细化我们的操作。
评分部分的代码中写着,

...class="form-control input-sm input-pjf"...

优缺点意见板块和总评语板块的class则分别是form-control input-zgpjform-control,分析完板块,我们就可以进行操作啦!

脚本编写

最简单无脑的一种填法是,把评分部分全部填上一个固定的数字,后边内容填上一个“无”。这只用对应上面网页分析中的两个板块了,但既然是原理分析,我们就详细一点。
首先,我们需要让机器知道咱们要操作的是什么。正如前文所说,我们看到的,是我们思考理解后的,操作机器则要使用机械的、数学的语言。
我们首先定义一个函数

function autoEvaluate() {
}

我们前面已经根据代码的class对不同的板块进行了分类,也定义了一个自动评教的主函数,那么我们接下来就可以分别对不同的板块进行操作了
首先是让计算机分开几个板块
以最后的优缺点板块为例,它和最后的总评价使用了同一种标签<textarea>,那么我们就可以查找到页面中所有使用该标签的内容。

var textareas = document.querySelectorAll('textarea');

接着对他们进行分类。我们注意到,同一类别的板块的输入框的class是一样的,哎,我们可以写一个循环来解决这个问题

//一个for循环,遍历每一个textarea
 for (var i = 0; i < textareas.length; i++) {
            //定义一个变量
            var textarea = textareas[i];
            // 根据不同的class输入不同的内容
            //class等不等于form-control input-zgpj
            if (textarea.className === 'form-control input-zgpj') {
            }
}

这样,最后那个括号里的情况就是class等于form-control input-zgpj,也就是优缺点板块的输入框了,我们写入代码就可以分别对其中的每个输入框进行操作。
哎,那能不能再区分优缺点来写呢?
很简单,我们再用写if就行,例如

                //我们知道,优缺点板块的第一个是“优点”输入框,我们定义一下i=0的情况即可(计算机从0开始数)
                if (i === 0) {
                    //填入内容,也就是修改该标签的值
                    textarea.value = '老师授课的方式非常适合我们,老师能根据本课程知识结构的特点,重点突出,层次分明。';
                } else {
                    //给缺点和意见填上“无”
                    textarea.value = '无';
                }
            //总评价板块
            } else if (textarea.className === 'form-control') {
                textarea.value = '老师对待教学认真负责,语言生动,条理清晰,举例充分恰当,对待学生严格要求,能够鼓励学生踊跃发言,使课堂气氛比较积极热烈。';
            }
        }

同理,我们也可以对评分的板块进行操作,为每一个输入框输入内容。
但是,执行的代码写完了,我们要让脚本知道什么时候开始执行,我给出的方法是在页面上添加一个按钮。

    // 创建一个固定定位的按钮
    var floatBtn = document.createElement('button');
    floatBtn.className = 'btn btn-success';
    floatBtn.textContent = '自动评教';
    floatBtn.style.position = 'fixed';
    floatBtn.style.bottom = '10px';
    floatBtn.style.right = '10px';
    floatBtn.style.zIndex = '9999';
    document.body.appendChild(floatBtn);

接着,将点击这个按钮的事件与执行函数绑定起来。

    // 给按钮添加点击事件,调用自动评教的函数
    floatBtn.addEventListener('click', autoEvaluate);

补完代码就算完成了,但需要注意,油猴脚本前面有一个“UserScript”部分,它是对该脚本的描述,如作者,协议,名称等等,需要注意的是,我们要想在教务系统中使用它,我们要定义该脚本的启用页面
这里直接用山传的域名

// @match        *://*.cusx.edu.cn/*

(完整代码见文末)*

改进

当然了,这个只不过是一个简易的版本,有很多改进的地方。例如,已经知道每一个板块的class了,我们完全可以直接查找这个class,而不用查找这个标签;其次,这样每次输入的内容都是固定的,完全可以使用一个随机函数,随机输入内容;除此之外,这个版本的脚本一次只能执行一个老师的评教,需要手动切换页面和保存,完全可以再写一个保存和切换老师的功能,在所有评价完后自动提交。(才不是因为作者懒得写


可以在Greasy Fork上直接安装我上传的脚本

网址:https://greasyfork.org/zh-CN/scripts/469411-自动评教-山传教务系统
注意,需要遵循使用协议哦,作者不对使用该脚本产生的任何问题负责,仅供交流学习使用。

完整代码:

// ==UserScript==
// @name         自动评教(山传教务系统)
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  运行后会在页面右下角添加一个“自动评教”按钮,点击后将会自动打分写评语。当前版本切换老师需要自己手动点击,(适用于“新教务系统”,8.2.23)后续提供自动切换老师和随机内容以及自动提交(这个版本作者懒得写了)
// @match        *://*.cusx.edu.cn/*
// @grant        none
// @author       Doubt-Fact
// ==/UserScript==

(function() {
    'use strict';

    // 定义一个自动评教的函数
    function autoEvaluate() {
        // 查找所有的input输入框
        var inputs = document.querySelectorAll('input');
        for (var i = 0; i < inputs.length; i++) {
            var input = inputs[i];
            // 根据不同的class输入不同的内容
            if (input.className === 'form-control input-sm input-pjf') {
                input.value = '100';
            }
        }

        // 查找所有的textarea输入框
        var textareas = document.querySelectorAll('textarea');
        for (var i = 0; i < textareas.length; i++) {
            var textarea = textareas[i];
            // 根据不同的class输入不同的内容
            if (textarea.className === 'form-control input-zgpj') {
                if (i === 0) {
                    textarea.value = '老师授课的方式非常适合我们,老师能根据本课程知识结构的特点,重点突出,层次分明。';
                } else {
                    textarea.value = '无';
                }
            } else if (textarea.className === 'form-control') {
                textarea.value = '老师对待教学认真负责,语言生动,条理清晰,举例充分恰当,对待学生严格要求,能够鼓励学生踊跃发言,使课堂气氛比较积极热烈。';
            }
        }

        // 不需要点击“提交”按钮
    }

    // 创建一个固定定位的按钮
    var floatBtn = document.createElement('button');
    floatBtn.className = 'btn btn-success';
    floatBtn.textContent = '自动评教';
    floatBtn.style.position = 'fixed';
    floatBtn.style.bottom = '10px';
    floatBtn.style.right = '10px';
    floatBtn.style.zIndex = '9999';
    document.body.appendChild(floatBtn);

    // 给按钮添加点击事件,调用自动评教的函数
    floatBtn.addEventListener('click', autoEvaluate);
})();

声明!!!

本文仅供交流学习使用,作者不负任何责任,请严格遵守校规校纪!!!

评论已关闭