WeLearn 自动挂机

用于WeLearn学习挂机,自动切换下一页,并模拟点击播放相关音频,避免出现“30分钟未学习”提示。此外,还在页面右上角添加一个“显示答案”的按钮,可用于检查答案是否正确。仅做测试用 建议使用Chrome浏览器。

  1. // ==UserScript==
  2. // @name WeLearn 自动挂机
  3. // @namespace https://github.com/hui-shao
  4. // @version 0.3
  5. // @description 用于WeLearn学习挂机,自动切换下一页,并模拟点击播放相关音频,避免出现“30分钟未学习”提示。此外,还在页面右上角添加一个“显示答案”的按钮,可用于检查答案是否正确。仅做测试用 建议使用Chrome浏览器。
  6. // @author hui-shao
  7. // @license GPLv3
  8. // @match http*://welearn.sflep.com/*/*tudyCourse.aspx*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=sflep.com
  10. // @grant none
  11. // @run-at document-idle
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16. function sleep(ms) {
  17. return new Promise((resolve) => setTimeout(resolve, ms));
  18. }
  19.  
  20. async function getDoc() {
  21. // 获取iframe并设置其加载完成的触发器
  22. for (let i = 1; i < 50; i++) {
  23. await sleep(100)
  24. var iframe = document.querySelector("#contentFrame");
  25. if (iframe) {
  26. iframe.onload = () => {
  27. doc = iframe.contentDocument;
  28. }
  29. break;
  30. }
  31. }
  32.  
  33. if (!iframe) {
  34. console.warn("[Script] Can not get iframe, Skip click function!")
  35. return false;
  36. }
  37.  
  38. // 等待从iframe获取到document
  39. for (let i = 0; i < 100; i++) {
  40. await sleep(200)
  41. if (doc) {
  42. return true;
  43. }
  44. }
  45. console.warn("[Script] Can not get document from iframe, Skip click function!")
  46. return false;
  47. }
  48.  
  49. function createButton() {
  50. var button = document.createElement("button");
  51. button.id = "btn001";
  52. button.textContent = "Loading...";
  53. button.style.color = "black";
  54. button.style.width = "110px";
  55. button.style.height = "90%";
  56. button.style.align = "center";
  57. button.style.marginRight = "0.5%";
  58. button.style.marginLeft = "-30%";
  59. doc.getElementsByClassName("controls")[0].appendChild(button);
  60.  
  61. let btn = doc.querySelector(".controls .sub .subInner et-button button");
  62. if (btn) {
  63. button.textContent = btn.firstChild.innerHTML;
  64. button.onclick = function () {
  65. console.log("[Script] Pressed the button.");
  66. btn.click();
  67. };
  68. }
  69. else {
  70. button.textContent = "None"
  71. console.warn("[Script] Can not find key/script btn");
  72. return;
  73. }
  74. }
  75.  
  76. function myClick() {
  77. var arr = null;
  78. var temp = null;
  79.  
  80. // 和下面一小段似乎有重复
  81. // arr = doc.getElementsByClassName("vjs-big-play-button");
  82. // if (arr.length) arr[0].click();
  83. // else console.log("[Script] Can not get vjs-big-play-button");
  84.  
  85. arr = doc.getElementsByClassName("vjs-play-control");
  86. if (arr.length) arr[0].click();
  87. else console.log("[Script] Can not get vjs-play-button");
  88.  
  89. temp = doc.querySelector("et-audio div");
  90. if (temp) temp.click();
  91. else console.log("[Script] Can not get et-audio div");
  92.  
  93. temp = doc.querySelector("et-button button[ng-click]");
  94. if (temp && temp.hasChildNodes()) {
  95. if (temp.childNodes[0].className.includes("microphone") || temp.childNodes[0].innerHTML.includes("Submit") || temp.childNodes[0].innerHTML.includes("Script") || temp.childNodes[0].innerHTML.includes("Key")) { } // 含有麦克风和Submit时跳过录音
  96. else temp.click();
  97. }
  98. else console.log("[Script] Can not get et-button button[ng-click]");
  99. }
  100.  
  101. function setRefreshOnNextButton() {
  102. var next_btn = null;
  103. next_btn = document.querySelector(".courseware_sidebar_2 .c_s_3_2");
  104. if (next_btn) {
  105. next_btn.onclick = () => {
  106. sleep(20).then(() => { location.reload(); });
  107. }
  108. }
  109. else console.warn("[Script] Can not get Next_Btn.")
  110. }
  111.  
  112. async function runClick() {
  113. await getDoc();
  114. if (doc) {
  115. var autoClick = setInterval(function () {
  116. console.log("click");
  117. myClick();
  118. }, (Math.round(Math.random() * 5 + 12)) * 1000); // 12~17s
  119.  
  120. createButton(); // 绘制KEY按钮
  121. }
  122. }
  123.  
  124. console.log("[Script] Script loaded.");
  125. var doc = null;
  126. var autoNext = setInterval(function () { // 放在外部 可以确保自动切换能正常运行, 防止脚本终止
  127. console.log("[Script] Next.");
  128. NextSCO(); // NextSCO() 是welearn网页定义的
  129. sleep(200).then(() => { location.reload(); }) // 刷新页面以便于重新加载运行脚本, 重新获取iframe
  130. }, (Math.round(Math.random() * 5 + 3)) * 1000 * 60);
  131.  
  132. document.onreadystatechange = function () {
  133. if (document.readyState == "complete") {
  134. setRefreshOnNextButton(); // 为手动点击Next按钮设置刷新任务
  135. }
  136. }
  137.  
  138. runClick();
  139.  
  140. })();

QingJ © 2025

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