# JavaScript强国自动答题脚本 **Repository Path**: sdasp/zddt ## Basic Information - **Project Name**: JavaScript强国自动答题脚本 - **Description**: 学X强G自动答题脚本,每题,每周,专题自动答题 - **Primary Language**: JavaScript - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: https://greasyfork.org/zh-CN/scripts/465896-%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-07-26 - **Last Updated**: 2023-07-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 自动答题脚本 #### 介绍 学习强国自动答题脚本,每题,每周,专题自动答题 #### 软件架构 软件架构说明 #### 安装教程 1. 安装Tampermonkey插件。 2. 在Tampermonkey创建脚本并使用js代码。 3. 登录学校强国网页版,进入答题界面,脚本自动执行。 #### 安装说明 1. 下载Tampermonkey文件夹,打开浏览器(以谷歌为例),点击右上角菜单列表(三个点),更多工具,扩展程序。 2. 进入扩展程序后,启用开发者模式,Tampermonkey_extension_4_9_0_0.crx,在弹窗中点击安装。 3. 安装完成后点击Tampermonkey图标进入插件,添加新脚本,将该代码复制保存即可。 4. 或直接在greasyfork中安装,地址见右侧[链接](https://greasyfork.org/zh-CN/scripts/465896-%E5%AD%A6%E4%B9%A0%E5%BC%BA%E5%9B%BD) #### 原理说明 学习强国在答题时会有“查看提示”按钮,当点击此按钮时,会触发一个新的div标签,标签内包含我们需要的正确答案。 ![输入图片说明](1.png) 正确答案字体为标红,匹配font标签,限定条件color="red" > var allTips=document.querySelectorAll("font[color=red]") 根据标签判断题型,选择题为q-answer,填空题为input > var buttons=document.querySelectorAll(".q-answer");  > var textboxs=document.querySelectorAll("input"); 根据题型不同选择相应的方式 填空题 需要考虑填空数量与提示数量相匹配的问题 首先判断填空数量,当填空数量不止一个时 > if( textboxs.length>1) 判断提示数量,是否与填空数量对应 > if(allTips.length==textboxs.length) 当数量对应时,循环遍历,一一匹配 ```js for (let i = 0; i < allTips.length; i++) { let tip = allTips[i]; let tipText = tip.textContent; //通过设置属性,然后立即让他冒泡这个input事件. if (tipText.length > 0) { //否则1,setattr后,内容消失. //否则2,element.value=124后,属性值value不会改变,所以冒泡也不管用. textboxs[i].setAttribute("value", tipText); textboxs[i].dispatchEvent(mevent); } } ``` 当填空数量与提示数量不同时,该情况分为填空数量多于提示和提示数量多于填空,一般情况下时提示数量多于填空,因为网页不会给出没有提示的问题。这个情况出现次数较少,我就不过多介绍。 > if(allTips.length>textboxs.length) 获取所有提示内容`var lineFeed = document.querySelector('.line-feed').textContent;` tip计数:> let n = 0; 遍历至多个填空 ```js for (let j = 0; j < textboxs.length; j++) { let tipText = allTips[n].textContent; let nextTipText = ""; do { tipText += nextTipText; if (n < textboxs.length - 1) { n++; nextTipText = allTips[n].textContent; } else { nextTipText = "结束"; } } while (lineFeed.indexOf(tipText + nextTipText)); textboxs[j].setAttribute("value", tipText); textboxs[j].dispatchEvent(mevent); } ``` 对于追求严谨的同学,也可以加上填空数量多于提示的事件,不过这样很难拆分答案,想加的就自己加吧。 当只有一个空时,大部分题目都是此类型,直接把所有的tips合并 ```js else if (textboxs.length == 1) { let tipText = ""; for (let i = 0; i < allTips.length; i++) { tipText += allTips[i].textContent; } textboxs[0].setAttribute("value", tipText); textboxs[0].dispatchEvent(mevent); break; } ``` 选择题分为单选和多选,两个题型的标签都一样,都是循环遍历点击,无非多选可以选多个,单选只能选一个而已。 ![输入图片说明](1683690263701.jpg) ![输入图片说明](1683690268531.jpg) 多选 首先循环选项 ```js for (let js = 0; js < buttons.length; js++) { let cButton = buttons[js]; } ``` 然后循环提示 ```js for (let i = 0; i < allTips.length; i++) { let tip = allTips[i]; let tipText = tip.textContent; } ``` 加个判断,提示内容不为空 ```js if (tipText.length > 0) { //获取按钮选项内容 let cButtonText = cButton.textContent; //循环对比点击 if (cButtonText.indexOf(tipText) > -1 || tipText.indexOf(cButtonText) > -1) { cButton.click(); break; } } ``` 单选和多选原理,但是用户反馈存在bug,所以单独拿出来说一下。 问题反馈:有时候单选提示会分成多个部分出现 处理:将标签内提示部分组合为一条 ```js if (true) { //把红色提示组合为一条 let tipText = ""; for (let i = 0; i < allTips.length; i++) { tipText += allTips[i].textContent; } if (tipText.length > 0) { //循环对比后点击 for (let js = 0; js < buttons.length; js++) { let cButton = buttons[js]; let cButtonText = cButton.textContent; //通过判断是否相互包含,来确认是不是此选项 if (cButtonText.indexOf(tipText) > -1 || tipText.indexOf(cButtonText) > -1) { cButton.click(); break; } } } } ``` If没有实际含义,case 里不能直接用let,所以增加了个if。