您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
导出瓴羊考试答题记录
/* * File: ly-certification.js * Project: ly-certification * Created: 2025-01-03 10:39:28 * Author: Victor Cheng * Email: [email protected] * Description: 瓴羊刷题助手 */ // 写一个Tampermonkey脚本 // 用在 https://cert.lydaas.com/cert-ly-online/exam/test 开头的网页 // 往页面上增加一个悬浮的 "导出答题记录" 按钮 // 点击这个按钮,查找文字内容为 "考试进度详情" 的div,然后找到它的下一个sibling节点,模拟点击这个节点里所有的子div节点 // 每次模拟点击,都把class名以 "_rightContent" 开头的div里的内容记录下来,具体要记录这些: // 1. 题型:class名以 "_questionType" 开头的节点里的文本内容 // 2. 题干:class名以 "_questionContent" 开头的节点里的文本内容 // 3. 选项:把class名以 "_optionText" 开头的所有节点里的文本内容拼接在一起,分隔符是 " | ",拼接时,按顺序给每个节点里的文本内容前面加上序号,例如 "A: 文本内容 | B: 文本内容 | C: 文本内容 | D: 文本内容" // 4. 正确答案:class名以 "_correctAnswers" 开头的节点里的span的文本内容 // 5. 我的答案:class名以 "_selectedAnswer" 开头的节点里的span的文本内容 // 6. 题目解析:内容以 "解析:" 开头的div里的span节点里的文本内容 // 7. 结果:查看class名以 "_selectedAnswer" 开头的节点里的span的文本内容,如果是 "未答题",结果就是 "未答题",否则把它与class名以 "_correctAnswers" 开头的节点里的span的文本内容比对,如果相同则结果为 "正确",否则为 "错误" // 所有模拟点击都完成后,把采集到的数据以一个csv文件形式存下来,csv的表头如下:题型 | 题干 | 选项 | 正确答案 | 我的答案 | 题目解析 | 结果 // 保存的文件名为当前时间加上 ".csv" 后缀,时间格式为 "ly_exam_YYYYMMDD_HHMMSS",例如 "ly_exam_20230101_123456.csv" // ==UserScript== // @name 瓴羊刷题助手 // @namespace http://tampermonkey.net/ // @version 1.0.2 // @description 导出瓴羊考试答题记录 // @author Victor Cheng // @match https://cert.lydaas.com/cert-ly-online/exam/test* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // 添加键盘事件监听 document.addEventListener('keydown', (event) => { console.log('键盘事件触发:', event.code); // 检查是否按下空格键且不是在输入框中 if (event.code === 'Space' && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) { // 阻止默认的空格滚动行为 event.preventDefault(); // 查找并点击下一题按钮 const nextButton = document.querySelector('[class^="ant-btn _next"]'); console.log('找到下一题按钮:', nextButton); if (nextButton) { console.log('点击下一题按钮'); nextButton.click(); } else { console.log('没有找到下一题按钮,可能的class名:', Array.from(document.querySelectorAll('button')) .map(btn => btn.className) .join(', ') ); } } }); // 创建悬浮按钮 const floatingButton = document.createElement('button'); floatingButton.textContent = '导出答题记录'; floatingButton.style.cssText = ` position: fixed; left: 16px; bottom: 16px; z-index: 9999; padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; `; document.body.appendChild(floatingButton); // 点击事件处理 floatingButton.addEventListener('click', async () => { // 禁用按钮,避免重复点击 floatingButton.disabled = true; floatingButton.textContent = '导出中...'; try { const records = []; // 查找考试进度详情div的下一个兄弟节点 const progressDiv = Array.from(document.querySelectorAll('div')).find(div => div.textContent.trim() === '考试进度详情'); console.log('找到考试进度详情:', progressDiv); if (!progressDiv) { throw new Error('未找到考试进度详情'); } const questionList = progressDiv.nextElementSibling; console.log('题目列表节点:', questionList); if (!questionList) { throw new Error('未找到题目列表'); } // 修改选择器以匹配实际的题目 div const questionDivs = questionList.querySelectorAll('[class^="_sheet_"]'); const totalQuestions = questionDivs.length; console.log('找到题目数量:', totalQuestions); // 遍历每个题目 for (let i = 0; i < totalQuestions; i++) { const div = questionDivs[i]; console.log(`处理第 ${i + 1} 题,class名:${div.className}`); // 更新按钮文本显示进度 floatingButton.textContent = `导出中...(${i + 1}/${totalQuestions})`; // 模拟点击 div.click(); console.log('已点击题目'); // 等待内容加载 await new Promise(resolve => setTimeout(resolve, 1000)); // 获取题目内容区域 const rightContent = document.querySelector('[class^="_rightContent"]'); console.log('题目内容区域:', rightContent); if (!rightContent) { console.warn('未找到题目内容区域'); continue; } // 获取各项内容 const questionType = rightContent.querySelector('[class^="_questionType"]')?.textContent?.trim() || ''; const questionContent = rightContent.querySelector('[class^="_questionContent"]')?.textContent?.trim() || ''; console.log('题型:', questionType); console.log('题干:', questionContent); // 获取选项 const options = Array.from(rightContent.querySelectorAll('[class^="_optionText"]')); console.log('选项数量:', options.length); const optionsText = options.map((opt, idx) => `${String.fromCharCode(65 + idx)}: ${opt.textContent.trim()}` ).join(' | '); console.log('选项内容:', optionsText); const correctAnswer = rightContent.querySelector('[class^="_correctAnswers"] span')?.textContent?.trim() || ''; const myAnswer = rightContent.querySelector('[class^="_selectedAnswer"] span')?.textContent?.trim() || ''; console.log('正确答案:', correctAnswer); console.log('我的答案:', myAnswer); // 获取解析 const analysisDiv = Array.from(rightContent.querySelectorAll('div')).find(div => div.textContent.trim().startsWith('解析:')); const analysis = analysisDiv?.querySelector('span')?.textContent?.trim() || ''; console.log('题目解析:', analysis); // 判断结果 let result = '未答题'; if (myAnswer && myAnswer !== '未答题') { result = myAnswer === correctAnswer ? '正确' : '错误'; } records.push({ 题型: questionType, 题干: questionContent, 选项: optionsText, 正确答案: correctAnswer, 我的答案: myAnswer, 题目解析: analysis, 结果: result }); } // 生成CSV内容 const headers = ['题型', '题干', '选项', '正确答案', '我的答案', '题目解析', '结果']; const csvRows = [ headers.join(','), ...records.map(record => headers.map(header => `"${(record[header] || '').toString().replace(/"/g, '""')}"` ).join(',') ) ]; const csvContent = '\ufeff' + csvRows.join('\n'); // 添加BOM标记以支持中文 // 下载CSV文件 const now = new Date(new Date().getTime() + 8 * 60 * 60 * 1000); // 转换为北京时间 const timestamp = now.toISOString() .replace(/[-:]/g, '') .replace(/T/, '_') .replace(/\..+/, ''); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `ly_exam_${timestamp}.csv`; link.click(); // 恢复按钮状态 floatingButton.textContent = '导出完成'; setTimeout(() => { floatingButton.disabled = false; floatingButton.textContent = '导出答题记录'; }, 2000); } catch (error) { alert('导出失败: ' + error.message); // 恢复按钮状态 floatingButton.disabled = false; floatingButton.textContent = '导出答题记录'; } }); })();