wsxy_autoExamineTest

网上学院函数库:自动答题

当前为 2020-02-10 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/395966/771519/wsxy_autoExamineTest.js

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name          wsxy_autoExamineTest
// @namespace     Vionlentmonkey
// @version       0.8
// @description   网上学院函数库:自动答题
// ==/UserScript==

/**
 * 获取各题答案。一次性数据,无存储必要
 * @param {String | Number} subjectPk
 */
const getSubjectData = async subjectPk => {
  const subjectURL = `${location.origin}/sfxzwsxy//jypxks/modules/train/course/subject_view.jsp?subjectPk=${subjectPk}`;
  const response = await fetch(subjectURL, {
    method: 'POST',
    body: 'blob'
  });
  const blob = await response.blob();
  const subjectHtml = await binary2Text(blob);
  const elements = htmlToElements(subjectHtml);
  // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map
  let subjectDataMap = new Map();
  // 题目类型:判断题/单选题/多选题
  const questionType = elements
    .querySelectorAll('table')[0]
    .querySelectorAll('tr')[0]
    .querySelectorAll('td')[1]
    .textContent.trim();
  subjectDataMap.set('questionType', questionType);
  // 题目内容:string
  const questionContent = elements
    .querySelectorAll('table')[0]
    .querySelectorAll('tr')[1]
    .querySelectorAll('td')[1]
    .textContent.trim();
  // 判断题答案,选择题此处为空值
  const judgementAnswer = elements
    .querySelectorAll('table')[0]
    .querySelectorAll('tr')[2]
    .querySelectorAll('td')[1]
    .textContent.trim();
  subjectDataMap.set('questionContent', questionContent);

  if (questionType === '判断题') {
    subjectDataMap.set('judgementAnswer', judgementAnswer);
  } else {
    // 选择题答案表格第一行为标题:序号 	 选项内容 	 类型 	 是否为标准答案
    // 此表格中答案选项与试题选项顺序打乱,序号没有意义,类型已获取也没有意义
    const options = elements.querySelectorAll('table')[1].querySelectorAll('tr');
    for (const option of options) {
      const optionContent = option.querySelectorAll('td')[1].textContent.trim();
      const optionAnswer = option.querySelectorAll('td')[3].textContent.trim();
      if (optionContent !== '选项内容' && optionAnswer !== '是否为标准答案') {
        subjectDataMap.set(optionContent, optionAnswer);
      }
    }
  }
  return subjectDataMap;
};

/**
 * 打开考卷后自动答题交卷
 */
const autoExamineTest = async () => {
  // 本考试所有试题
  const topics = document.getElementsByClassName('topic-tms');
  for await (const topic of topics) {
    // 题号
    const pkid = topic.querySelector('a[pkid]').getAttribute('pkid');
    // 本题答案
    const subjectDataMap = await getSubjectData(pkid);
    // 本题选项
    const options = topic.querySelectorAll('.tms-Right-wrong > p > a');
    for (const option of options) {
      const optionText = option.textContent.trim();
      if (subjectDataMap.get('questionType') === '判断题') {
        if (option.textContent.trim() === subjectDataMap.get('judgementAnswer')) {
          option.click();
        }
      } else {
        // 选择题选项内容带着序号与空格,如“A ”,故获取第三个字符开始的子串
        if (subjectDataMap.get(optionText.substring(2)) === '是') {
          option.click();
        }
      }
    }
  }
  // 交卷
  if (document.getElementsByClassName('subline _submit').length === 1) {
    document.getElementsByClassName('subline _submit')[0].click();
  }
  // 确认
  if (document.getElementsByClassName('layui-layer-btn0').length === 1) {
    document.getElementsByClassName('layui-layer-btn0')[0].click();
  }
};