北大青鸟云题库解析

启动!

// ==UserScript==
// @name         北大青鸟云题库解析
// @namespace    http://tampermonkey.net/
// @version      0.0.6
// @description  启动!
// @author       超级猫猫头
// @match        https://tiku.kgc.cn/*
// @icon         https://webstatic.mihoyo.com/bh3/upload/officialsites/201908/ys_1565764084_7084.png
// @grant        none
// @license      GNU GPLv3
// @run-at       document-end
// ==/UserScript==

// 检查localStorage中是否已经有firstUse的记录
let firstUse = localStorage.getItem('firstUse') === 'true';

// 显示免责声明和使用说明
if (!firstUse) {
    const userConsent = prompt("欢迎使用北大青鸟云题库解析脚本!\n\n本脚本仅供学习参考使用,不得用于考试作弊等用途。\n请支持原创,任何形式的二次倒卖、转售或出租本脚本的行为均属违法,一经发现,将追究法律责任。\n\n使用本脚本即表示您同意遵守相关法律法规和道德规范。\n\n请输入 '同意' 以继续使用本脚本。");
    if (userConsent === "同意") {
        alert("欢迎使用北大青鸟云题库解析脚本!\n\n按下回车键以开始获取题目解析。\n\n按下j键可在题目报告页一键全对。\n\n按下esc键输出解析。");
        firstUse = true; // 用户同意免责声明,设置firstUse为true
        localStorage.setItem('firstUse', 'true'); // 将firstUse状态保存到localStorage中
    } else {
        alert("您未同意免责声明,如果不想使用脚本可以将脚本删除。");
        throw new Error("用户未同意免责声明,脚本终止执行。"); // 禁止用户使用脚本的所有功能
    }
}


let isFetchingAnalysis = false; // 新增变量,用于跟踪是否正在获取解析

// 等待用户按下回车键
function waitForEnter() {
    return new Promise(resolve => {
        document.addEventListener('keydown', function onKeydown(event) {
            if (event.key === 'Enter') {
                resolve();
            }
        });
    });
}

// 清理 HTML 内容
function cleanHtmlContent(content) {
    // 将 HTML 实体转换为对应的字符
    content = content.replace(/ /g, ' ');
    // 移除所有的 HTML 标签
    content = content.replace(/<[^>]+>/g, '');
    // 移除换行符 \r\n
    content = content.replace(/\r\n/g, ' ');
    return content;
}

// 获取题目解析
async function getQuestionAnalysis() {
    if (isFetchingAnalysis) {
        console.log('已经有获取解析的操作正在进行,忽略本次请求。');
        return;
    }

    isFetchingAnalysis = true; // 设置为正在获取解析

    // 创建进度显示元素
    const progressElement = document.createElement('div');
    progressElement.style.position = 'fixed';
    progressElement.style.top = '10px';
    progressElement.style.right = '10px';
    progressElement.style.backgroundColor = 'rgb(51, 51, 51)'; // 修改此处颜色
    progressElement.style.border = 'none'; // 去除外边框
    progressElement.style.padding = '5px';
    progressElement.style.zIndex = 1000;
    progressElement.style.color = 'rgb(160, 192, 1)'; // 修改文字颜色
    document.body.appendChild(progressElement);

    // 获取网页源代码
    const pageSource = document.documentElement.outerHTML;

    // 使用正则表达式查找题目 id
    const pattern = /javascript:markQuestion\((\d+)\)/g;
    let matches;
    const analysisList = [];
    const processedIds = new Set();
    let id = 0; // 初始化计数器为0

    while ((matches = pattern.exec(pageSource)) !== null) {
        const questionId = matches[1];
        if (!processedIds.has(questionId)) {
            processedIds.add(questionId);
            id += 1; // 每次循环开始时递增计数器

            // 更新进度显示
            progressElement.textContent = `正在获取第 ${id} 题的解析...`;

            // 拼接 URL
            const url = `https://tiku.kgc.cn/testing/questionAnalysis/${questionId}`;

            // 使用 fetch API 获取解析内容
            const response = await fetch(url);
            const analysis = await response.text();

            // 使用正则表达式匹配 "content" 字段
            const contentPattern = /"content":"([^"]*)"/g;
            let contentMatches;
            let contentId = 0;
            while ((contentMatches = contentPattern.exec(analysis)) !== null) {
                contentId += 1;
                const content = contentMatches[1];
                // 清理 HTML 内容
                const cleanContent = cleanHtmlContent(content);
                analysisList.push({ id, contentId, content: cleanContent });
            }
        }
    }

    // 所有解析获取完毕,更新进度显示
    progressElement.textContent = '所有解析已获取完毕(按下esc键输出解析)';

    // 等待2秒后隐藏进度显示元素
    setTimeout(() => {
        progressElement.style.display = 'none';
    }, 2000);

    // 在这里保存解析,而不是立即输出
    // 假设我们将解析保存在一个全局变量中
    window.analysisList = analysisList;

    isFetchingAnalysis = false; // 获取解析完成,设置为未在获取解析
}

// 监听回车键按下事件
document.addEventListener('keydown', async function onKeydown(event) {
    if (event.key === 'Enter') {
        await getQuestionAnalysis();
    }
});

// 监听 ESC 键按下事件
document.addEventListener('keydown', async function onKeydown(event) {
    if (event.key === 'Escape') {
        // 在这里输出之前保存的解析
        const outputWindow = window.open('', '_blank');
        if (window.analysisList) {
            window.analysisList.forEach(({ id, contentId, content }) => {
                if (content) {
                    // 在每个解析后添加换行符
                    outputWindow.document.write(`第 ${id} 题的第 ${contentId} 个解析: ${content}<br><br>`);
                } else {
                    outputWindow.document.write(`第 ${id} 题的第 ${contentId} 个解析未找到<br><br>`);
                }
            });
        } else {
            outputWindow.document.write('暂无解析内容');
        }
    }
});

//自由改名
const userNameElement = document.getElementById('userName');
if (userNameElement) {
    userNameElement.contentEditable = true;
}

// 一键全对
document.addEventListener('keydown', function onKeydown(event) {
    if (event.key === 'j') {
        
        // 使用 XPath 查找包含 "本次考试得分为:" 的元素
        function findScoreElement() {
            const xpath = "//span[contains(text(), '本次考试得分为:')]";
            return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        }

        // 获取<span class="reds">元素中的得分
        const redsElement = document.querySelector('span.reds');
        if (redsElement) {
            // 将得分更改为100
            redsElement.textContent = '100';
        }

        // 使用 XPath 查找得分元素并修改其内容
        const scoreElement = findScoreElement();
        if (scoreElement) {
            scoreElement.innerHTML = '本次考试得分为:<i>100分</i>';
        }

        // 获取所有class="red"的li元素
        const redListElements = document.getElementsByClassName('red');

        // 使用forEach方法一次性移除所有元素的red属性
        Array.from(redListElements).forEach(element => {
            element.classList.remove('red');
        });

        // 获取<p class="grays">元素中的x
        const graysElement = document.querySelector('p.grays');
        if (graysElement) {
            const text = graysElement.textContent;
            const match = text.match(/共(\d+)道题/);
            if (match) {
                const x = match[1];

                // 获取<p class="size">元素
                const sizeElement = document.querySelector('p.size');
                if (sizeElement) {
                    sizeElement.textContent = `${x}`;
                }
            }
        }
    }
});

QingJ © 2025

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