Greasy Fork is available in English.
自动检测 cloud.italent.cn 考试题目并查询答案,高亮显示正确答案 + 支持题库上传功能
当前为
// ==UserScript==
// @name iTalent 在线考试自动答题助手(带题库上传)
// @namespace https://yangtaoer.com.cn/
// @version 1.5
// @description 自动检测 cloud.italent.cn 考试题目并查询答案,高亮显示正确答案 + 支持题库上传功能
// @author yang
// @match https://cloud.italent.cn/*
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @connect yangtaoer.com.cn
// @license MIT
// ==/UserScript==
(function () {
'use strict';
const CONFIG = {
apiUrl: 'https://yangtaoer.com.cn/exam/api/parse',
uploadUrl: 'https://yangtaoer.com.cn/exam/api/upload',
checkInterval: 2000,
targetKeyword: 'RestGetExamResultAndAnalysisByResultID',
};
let knownQuestions = new Set();
let paused = false;
let cachedResultJson = null; // 保存捕获到的题库数据
// === UI面板 ===
const panel = document.createElement('div');
panel.innerHTML = `
<div id="exam-helper-panel">
<button id="exam-helper-toggle">⏸ 暂停检测</button>
<button id="exam-helper-clear">🧹 清空标记</button>
<button id="exam-helper-upload">📤 上传题库</button>
<span id="exam-helper-status">状态:运行中</span>
</div>
`;
document.body.appendChild(panel);
GM_addStyle(`
#exam-helper-panel {
position: fixed;
top: 80px;
right: 30px;
background: rgba(0,0,0,0.75);
color: #fff;
padding: 10px 15px;
border-radius: 10px;
z-index: 999999;
font-size: 14px;
box-shadow: 0 0 10px rgba(0,0,0,0.4);
}
#exam-helper-panel button {
margin: 2px 5px;
background: #2e8b57;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
#exam-helper-panel button:hover {
background: #3cb371;
}
.exam-highlight {
background-color: #38e42c !important;
position: relative;
}
.exam-highlight::after {
content: "√";
color: red;
font-weight: bold;
margin-left: 5px;
}
`);
// === UI交互 ===
document.getElementById('exam-helper-toggle').onclick = () => {
paused = !paused;
document.getElementById('exam-helper-toggle').innerText = paused ? '▶ 开始检测' : '⏸ 暂停检测';
document.getElementById('exam-helper-status').innerText = `状态:${paused ? '暂停' : '运行中'}`;
};
document.getElementById('exam-helper-clear').onclick = () => {
document.querySelectorAll('.exam-highlight').forEach(e => e.classList.remove('exam-highlight'));
knownQuestions.clear();
console.log('✅ [答题助手] 已清空标记与缓存');
showToast('✅ 已清空标记与缓存');
};
// === 上传按钮逻辑 ===
document.getElementById('exam-helper-upload').onclick = () => {
if (!cachedResultJson) {
showToast('⚠️ 未检测到任何 “RestGetExamResultAndAnalysisByResultID” 请求数据!', 'warn');
console.warn('未捕获到目标请求数据');
return;
}
showToast('⏳ 正在上传题库,请稍候...');
GM_xmlhttpRequest({
method: 'POST',
url: CONFIG.uploadUrl,
headers: { 'Content-Type': 'application/json' },
data: JSON.stringify(cachedResultJson),
onload: res => {
if (res.status === 200) {
showToast('✅ 题库上传成功!');
console.log('上传响应:', res.responseText);
} else {
showToast('❌ 上传失败,请检查网络或接口', 'error');
}
},
onerror: err => {
console.error('上传失败', err);
showToast('❌ 上传失败,请检查网络', 'error');
}
});
};
// === Toast 弹窗 ===
function showToast(msg, type = 'info') {
const div = document.createElement('div');
div.innerText = msg;
div.style.position = 'fixed';
div.style.bottom = '100px';
div.style.right = '40px';
div.style.padding = '10px 20px';
div.style.background = type === 'error' ? '#ff4d4f' :
type === 'warn' ? '#faad14' :
'#52c41a';
div.style.color = '#fff';
div.style.borderRadius = '8px';
div.style.fontSize = '14px';
div.style.zIndex = 999999;
div.style.boxShadow = '0 0 6px rgba(0,0,0,0.3)';
document.body.appendChild(div);
setTimeout(() => div.remove(), 2500);
}
// === 捕获请求 ===
function interceptRequests() {
// --- XMLHttpRequest ---
const _open = XMLHttpRequest.prototype.open;
const _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function (...args) {
this._url = args[1];
return _open.apply(this, args);
};
XMLHttpRequest.prototype.send = function (...args) {
this.addEventListener('load', function () {
try {
if (this._url && this._url.includes(CONFIG.targetKeyword)) {
const text = this.responseText;
const json = JSON.parse(text);
cachedResultJson = json;
console.log('🎯 捕获到 RestGetExamResultAndAnalysisByResultID 请求响应:', json);
showToast('✅ 已捕获考试结果数据,可上传题库');
}
} catch (e) {
console.warn('捕获请求解析失败:', e);
}
});
return _send.apply(this, args);
};
// --- fetch ---
const _fetch = window.fetch;
window.fetch = async function (...args) {
const response = await _fetch(...args);
const url = args[0];
if (typeof url === 'string' && url.includes(CONFIG.targetKeyword)) {
try {
const clone = response.clone();
const text = await clone.text();
const json = JSON.parse(text);
cachedResultJson = json;
console.log('🎯 捕获到 fetch 请求响应:', json);
showToast('✅ 已捕获考试结果数据,可上传题库');
} catch (e) {
console.warn('fetch 响应解析失败:', e);
}
}
return response;
};
}
// === 抓题逻辑 ===
function extractQuestions() {
const titles = Array.from(document.getElementsByClassName('exam-topic-item-title-name'));
const result = [];
titles.forEach(el => {
const text = el.innerText.trim();
if (text && !knownQuestions.has(text)) {
knownQuestions.add(text);
result.push(text);
}
});
return result;
}
function highlightAnswer(index, answers) {
const wrapper = document.getElementsByClassName('exam-options-wrapper')[index];
if (!wrapper) return;
answers.forEach(ans => {
let matched = false;
wrapper.childNodes.forEach(node => {
try {
const content = node.childNodes[1]?.childNodes[0]?.innerText?.trim();
if (content === ans) {
node.classList.add('exam-highlight');
matched = true;
}
} catch {}
});
if (!matched) console.warn(`⚠️ 题号 ${index + 1}: 未匹配答案 ${ans}`);
});
}
function queryAnswers(questions) {
if (questions.length === 0) return;
console.log(`🔍 新检测到 ${questions.length} 道题,正在查询...`);
GM_xmlhttpRequest({
method: 'POST',
url: CONFIG.apiUrl,
headers: { 'Content-Type': 'application/json' },
data: JSON.stringify(questions),
onload: res => {
try {
const data = JSON.parse(res.responseText).data || [];
data.forEach((e, i) => e.answer.length && highlightAnswer(i, e.answer));
} catch (err) {
console.error('❌ 解析接口返回错误', err);
}
},
onerror: err => console.error('❌ 查询接口请求失败', err)
});
}
// === 定时检测题目 ===
setInterval(() => {
if (paused) return;
const newQuestions = extractQuestions();
if (newQuestions.length > 0) queryAnswers(newQuestions);
}, CONFIG.checkInterval);
interceptRequests();
console.log('✅ [iTalent 答题助手 v1.5] 已启动(含题库上传增强)');
})();