Extract MCQs from the webpage
当前为
// ==UserScript==
// @name Extract MCQs
// @namespace themrsami
// @version 2.0
// @description Extract MCQs from the webpage
// @author You
// @match http://*/*
// @match https://*/*
// @grant GM_registerMenuCommand
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Add some CSS for the button
GM_addStyle(`
#extract-mcqs-button {
position: fixed;
bottom: 20px;
right: 20px;
padding: 10px 20px;
font-size: 16px;
color: white;
background-color: #007BFF;
border: none;
border-radius: 5px;
cursor: pointer;
z-index: 9999;
}
#extract-mcqs-button:hover {
background-color: #0056b3;
}
`);
// Create the button
let button = document.createElement('button');
button.id = 'extract-mcqs-button';
button.innerText = 'Extract MCQs';
document.body.appendChild(button);
GM_registerMenuCommand('Extract MCQs', function() {
// Remove elements that destroy the structure
let elementsToRemove = [
...document.querySelectorAll('div[style="margin:30px 0px;"]'),
...document.querySelectorAll('div.sf-mobile-ads'),
...document.querySelectorAll('div.sf-desktop-ads'),
...document.querySelectorAll('span.collapseomatic')
];
for (let element of elementsToRemove) {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
}
let pTags = document.getElementsByTagName('p');
let results = [];
for (let i = 0; i < pTags.length; i++) {
let imgHref = null;
let aTag = pTags[i].getElementsByTagName('a')[0];
if (aTag) {
let imgTag = aTag.getElementsByTagName('img')[0];
if (imgTag) {
imgHref = imgTag.src || imgTag.getAttribute('data-src');
aTag.parentNode.removeChild(aTag);
}
}
let startsWithNumber = /^\d/.test(pTags[i].textContent);
let nextSibling = pTags[i].nextElementSibling;
if (startsWithNumber && nextSibling && nextSibling.tagName.toLowerCase() === 'div' && nextSibling.classList.contains('collapseomatic_content')) {
let statementAndOptions = pTags[i].innerHTML.split('<br>');
let statement = statementAndOptions.shift();
let options = statementAndOptions.join('<br>').replace(/\n/g, '');
let answerAndExplanation = nextSibling.innerHTML.split('<br>');
let answer = answerAndExplanation.shift().replace(/\n/g, '');
let explanation = answerAndExplanation.join('<br>').replace(/\n/g, '');
results.push({
statement: statement,
imgHref: imgHref,
options: options,
answer: answer,
explanation: explanation
});
}
let nextDiv = pTags[i].nextElementSibling;
if (nextDiv && nextDiv.tagName.toLowerCase() === 'div' && nextDiv.classList.contains('hk1_style-wrap5')) {
let pre = nextDiv.getElementsByTagName('pre')[0];
if (pre) {
let nextP = nextDiv.nextElementSibling;
if (nextP && nextP.tagName.toLowerCase() === 'p') {
let nextDiv2 = nextP.nextElementSibling;
if (nextDiv2 && nextDiv2.tagName.toLowerCase() === 'div' && nextDiv2.classList.contains('collapseomatic_content')) {
let statement = pTags[i].textContent;
let preContent = pre.textContent.replace(/\n/g, '');
let options = nextP.innerHTML.split('<br>').join('<br>').replace(/\n/g, '');
let answerAndExplanation = nextDiv2.innerHTML.split('<br>');
let answer = answerAndExplanation.shift().replace(/\n/g, '');
let explanation = answerAndExplanation.join('<br>').replace(/\n/g, '');
results.push({
statement: statement,
preContent: preContent,
options: options,
answer: answer,
explanation: explanation
});
}
}
}
let del1 = nextDiv.getElementsByClassName('del1')[0];
if (del1) {
let statement = pTags[i].textContent + ' ' + del1.textContent;
let nextP = nextDiv.nextElementSibling;
if (nextP && nextP.tagName.toLowerCase() === 'p') {
let nextDiv2 = nextP.nextElementSibling;
if (nextDiv2 && nextDiv2.tagName.toLowerCase() === 'div' && nextDiv2.classList.contains('collapseomatic_content')) {
let options = nextP.innerHTML.split('<br>').join('<br>').replace(/\n/g, '');
let answerAndExplanation = nextDiv2.innerHTML.split('<br>');
let answer = answerAndExplanation.shift().replace(/\n/g, '');
let explanation = answerAndExplanation.join('<br>').replace(/\n/g, '');
results.push({
statement: statement,
options: options,
answer: answer,
explanation: explanation
});
}
}
}
}
}
console.log(JSON.stringify(results, null, 2));
// ... Your existing code to extract the MCQs ...
// Now let's generate the HTML
let html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"="width=device-width, initial-scale=1.0">
<title>Quiz</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@tailwind base;
@tailwind components;
@tailwind utilities;
.option:hover:not(.selected) {
@apply bg-gray-300;
}
.correct {
@apply bg-green-200;
}
.incorrect {
@apply bg-red-200;
}
.selected {
@apply bg-gray-400;
}
.option:hover {
@apply scale-105;
}
.selected {
@apply scale-110;
}
.option:focus {
@apply ring-4 ring-blue-500 ring-offset-2 ring-offset-gray-100;
}
</style>
</head>
<body class="bg-gray-100 p-10">
<div class="flex justify-between items-center mb-4 sticky top-0 bg-white z-50">
<div>
<p class="text-lg font-bold">Time: <span id="timer" class="text-blue-500">00:00</span></p>
</div>
<div>
<p class="text-lg font-bold text-green-500">Correct: <span id="correct-count">0</span></p>
<p class="text-lg font-bold text-red-500">Incorrect: <span id="incorrect-count">0</span></p>
</div>
</div>
${results.map((result, index) => `
<div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 flex flex-col my-2">
<div class="md:flex mb-6">
<div class="md:w-1/2 px-3">
<label class="block uppercase tracking-wide text-blue-900 text-lg font-bold mb-2" for="grid-first-name">
Q${index + 1}: ${result.statement.replace(/^\d+\.\s*/, '')}
</label>
${result.preContent ? `<pre>${result.preContent}</pre>` : ''}
</div>
<div class="md:w-1/2 px-3">
${result.imgHref ? `<img src="${result.imgHref}" alt="Image" class="mb-4">` : ''}
</div>
</div>
<div class="md:flex mb-6">
<div class="md:w-full px-3">
<div id="options-${index}" class="grid grid-cols-1 md:grid-cols-2 gap-4">
${result.options.split('<br>').map((option, optionIndex) => option.trim() !== "" ? `
<p class="option cursor-pointer py-2 px-4 rounded bg-blue-100 hover:bg-blue-200" onclick="checkAnswer(${index}, ${optionIndex})">${option}</p>
` : '').join('')}
</div>
<button class="mt-3 text-white bg-blue-700 border-0 py-2 px-6 focus:outline-none hover:bg-blue-800 rounded text-lg" onclick="document.getElementById('answer-${index}').classList.toggle('hidden');document.getElementById('explanation-${index}').classList.toggle('hidden');">Show/Hide Answer</button>
<p id="answer-${index}" class="hidden mt-3 text-grey-darker text-base bg-gray-200 p-4 rounded">${result.answer}</p>
<p id="explanation-${index}" class="hidden mt-3 text-grey-darker text-base bg-gray-200 p-4 rounded">${result.explanation}</p>
</div>
</div>
</div>
`).join('')}
<script src="script.js"></script>
</body>
</html>`;
// Download the file
let blob = new Blob([html], {type: "text/html;charset=utf-8"});
let link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "quiz.html";
link.click();});
// Add an event listener to the button
button.addEventListener('click', function() {
// Execute the menu command
GM_executeMenuCommand('Extract MCQs');
});
})();