华医网自动答题(仅限刷完视频的课程)

123

  1. // ==UserScript==
  2. // @name 华医网自动答题(仅限刷完视频的课程)
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-11-04
  5. // @description 123
  6. // @author You
  7. // @match https://cme28.91huayi.com/pages/course.aspx?cid=*
  8. // @match https://cme28.91huayi.com/pages/exam.aspx?cwid=*
  9. // @match https://cme28.91huayi.com/pages/exam_result.aspx?cwid=*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=91huayi.com
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function () {
  15.  
  16. // 一秒后执行
  17. setTimeout(start, 1000);
  18.  
  19. // 启动方法
  20. function start() {
  21. // 待考试url
  22. const todoUrl = 'https://cme28.91huayi.com/pages/exam_result.aspx?cwid=';
  23. const doingUrl = 'https://cme28.91huayi.com/pages/exam.aspx?cwid=';
  24. const courseUrl = 'https://cme28.91huayi.com/pages/course.aspx?cid=';
  25.  
  26. // 考试通过页面
  27. if (window.location.href.includes(todoUrl)) {
  28. if (document.getElementsByClassName('tips_text')[0].innerText.includes('未通过')) {
  29. // 考试未通过,采集答案
  30. const answerTitle = localStorage.getItem("answer");
  31. let answerTitleMap;
  32. if (answerTitle === null || answerTitle === undefined) {
  33. answerTitleMap = new Map()
  34. } else {
  35. answerTitleMap = jsonToMap(answerTitle);
  36. }
  37.  
  38. const state_cour_lis = document.getElementsByClassName('state_cour_lis');
  39. // 题目集合
  40. for (let stateCour of state_cour_lis) {
  41. // 正确答案,跳过
  42. const flag = stateCour.getElementsByClassName('state_error')[0].getAttribute('src').includes('bar_img.png');
  43. if (flag) {
  44. continue;
  45. }
  46. const state_lis_text = stateCour.getElementsByClassName('state_lis_text');
  47. const questionTitle = getContentAfterFirstSeparator(state_lis_text[0].getAttribute('title')); // 题目标题
  48. const answerTitle = state_lis_text[1].getAttribute('title'); // 答案标题
  49. if (answerTitleMap.has(questionTitle)) {
  50. answerTitleMap.set(questionTitle, answerTitleMap.get(questionTitle) + ',' + answerTitle)
  51. } else {
  52. answerTitleMap.set(questionTitle, answerTitle)
  53. }
  54. }
  55. console.log('缓存错误答案:', answerTitleMap);
  56. localStorage.setItem('answer', mapToJson(answerTitleMap));
  57. setTimeout(() => {
  58. document.getElementsByClassName('state_foot_btn state_edu')[1].click();
  59. }, 3000);
  60. } else {
  61. // 考试通过,更新缓存
  62. const todo = getCache(false);
  63. todo.set(new URLSearchParams(window.location.search).get('cwid'), '已完成')
  64. localStorage.setItem('todo', mapToJson(todo))
  65. localStorage.removeItem('answer');
  66. // 查找待考试
  67. const cwrid = findKeyByValueInMap(todo, '待考试');
  68.  
  69. setTimeout(()=>{
  70. // 跳转考试页面
  71. window.location.href = doingUrl + cwrid;
  72. },3000)
  73. }
  74. }
  75. // 答题页面
  76. if (window.location.href.includes(doingUrl)) {
  77. console.log("开始答题");
  78. const q_nameList = document.getElementsByClassName('tablestyle');
  79. console.log(`页面一共有${q_nameList.length}道题目`)
  80.  
  81. // 循环题目
  82. for (let q_nameTmp of q_nameList) {
  83. let q_name = q_nameTmp.getElementsByClassName('q_name')[0];
  84. // 题目id
  85. const data_qid = q_name.getAttribute('data-qid');
  86. const q_nametitle = getContentAfterFirstSeparator(q_name.textContent);
  87.  
  88. // 选项集合
  89. const qo_nameList = document.getElementsByClassName('qo_name');
  90.  
  91. // 已选标记位
  92. let breakFlag = false;
  93.  
  94. // 循环选项
  95. for (let qo_name of qo_nameList) {
  96. const elementsByTagNameElement = q_nameTmp.getElementsByTagName('tbody')[0];
  97. const elementsByTagName = elementsByTagNameElement.getElementsByTagName('label');
  98.  
  99. for (let elementsByTagNameElement1 of elementsByTagName) {
  100. const label = elementsByTagNameElement1.textContent;
  101. const labelText = removeExtraSpacesAndNewlines(label);
  102. const qo_nameId = qo_name.getAttribute('name');
  103. if (breakFlag || !qo_nameId.includes(data_qid)) {
  104. // 执行跳出循环后的逻辑
  105. continue;
  106. }
  107. console.log(`开始答题,题目:${q_name.innerText},答案:${labelText}`)
  108. // 获取缓存Cache
  109. const answerCache = localStorage.getItem('answer');
  110. // 首次加载,没有缓存情况,直接使用第一次遇到的选项
  111. if (answerCache === null || answerCache === undefined) {
  112. // 点击选项
  113. elementsByTagNameElement1.click();
  114. // 已选标记位
  115. breakFlag = true;
  116. } else {
  117. let map = jsonToMap(answerCache);
  118. let value = map.get(q_nametitle);
  119. if (value === null || value === undefined) {
  120. // 点击
  121. elementsByTagNameElement1.click();
  122. breakFlag = true;
  123. } else {
  124. value = String(value);
  125. if (value.includes(labelText)) {
  126. console.log(`排除答案:${labelText}`)
  127. } else {
  128. // 点击
  129. elementsByTagNameElement1.click();
  130. breakFlag = true;
  131. }
  132. }
  133.  
  134. }
  135. }
  136.  
  137.  
  138. }
  139. }
  140.  
  141. console.log('模拟提交')
  142. setTimeout(() => {
  143. document.getElementById('btn_submit').click()
  144. }, 3000)
  145. }
  146.  
  147. // 课程页面
  148. if (window.location.href.includes(courseUrl)) {
  149. const todo = getCache(true);
  150. console.log(todo);
  151. // 查找待考试
  152. const cwrid = findKeyByValueInMap(todo, '待考试');
  153. // 跳转考试页面
  154. window.location.href = doingUrl + cwrid;
  155. console.log("课程页面")
  156. }
  157. }
  158.  
  159. function removeExtraSpacesAndNewlines(str) {
  160. return str.replace(/\s+/g, ' ').replace(/\n/g, '').trim();
  161. }
  162.  
  163. function getCache(needUpdate) {
  164. // 查看缓存是否有有未考试的课程
  165. let todo = localStorage.getItem('todo')
  166. if (todo === null || needUpdate) {
  167. let todoMap = new Map();
  168. const course = document.getElementsByClassName('course');
  169. if (course.length === 0) {
  170. return;
  171. }
  172. for (let courseElement of course) {
  173. const spans = courseElement.getElementsByTagName('span');
  174. const value = spans[0].innerText + '';
  175. const key = spans[1].getAttribute('data-cwrid') + '';
  176. todoMap.set(key, value);
  177. console.log('已添加课程:%s,当前状态:%s', key, value)
  178. }
  179. localStorage.setItem('todo', mapToJson(todoMap));
  180. return todoMap;
  181. } else {
  182. return jsonToMap(todo);
  183. }
  184. }
  185.  
  186. function getContentAfterFirstSeparator(str) {
  187. let strTmp = String(str)
  188. let index = strTmp.indexOf('、');
  189. if (index!== -1) {
  190. return strTmp.substring(index + 1);
  191. } else {
  192. return strTmp;
  193. }
  194. }
  195.  
  196. function findKeyByValueInMap(map, value) {
  197. for (const [key, val] of map) {
  198. if (val === value) {
  199. return key;
  200. }
  201. }
  202. return null;
  203. }
  204.  
  205. function jsonToMap(jsonStr) {
  206. const obj = JSON.parse(jsonStr);
  207. const map = new Map();
  208. for (const key in obj) {
  209. if (obj.hasOwnProperty(key)) {
  210. map.set(key, obj[key]);
  211. }
  212. }
  213. return map;
  214. }
  215.  
  216. function mapToJson(map) {
  217. if (map === null || map.size === 0) {
  218. return;
  219. }
  220. const obj = {};
  221. for (const [key, value] of map) {
  222. obj[key] = value;
  223. }
  224. return JSON.stringify(obj);
  225. }
  226. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址