mirror of
https://git.victorphan.net/basketballcantho/study4.git
synced 2026-08-05 14:23:11 +07:00
Add source code, scraper extension, and result files
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
(function() {
|
||||
function extractData(doc) {
|
||||
let items = [];
|
||||
const blocks = doc.querySelectorAll('.termlist-item.contentblock');
|
||||
|
||||
blocks.forEach(block => {
|
||||
let word = "";
|
||||
let type = "";
|
||||
let pronunciation = "";
|
||||
|
||||
// Extract from h2
|
||||
const h2 = block.querySelector('h2.h3');
|
||||
if (h2) {
|
||||
// Word is typically the first text node
|
||||
word = Array.from(h2.childNodes)
|
||||
.filter(node => node.nodeType === Node.TEXT_NODE)
|
||||
.map(node => node.textContent.trim())
|
||||
.join(' ')
|
||||
.trim();
|
||||
|
||||
const spans = h2.querySelectorAll('span');
|
||||
if (spans.length >= 2) {
|
||||
type = spans[0].textContent.trim();
|
||||
pronunciation = spans[1].textContent.trim();
|
||||
} else if (spans.length === 1) {
|
||||
type = spans[0].textContent.trim();
|
||||
}
|
||||
}
|
||||
|
||||
// Definition
|
||||
let definition = "";
|
||||
const defDiv = block.querySelector('.prewrap.mb-2');
|
||||
if (defDiv) {
|
||||
definition = defDiv.textContent.trim();
|
||||
}
|
||||
|
||||
// Examples
|
||||
let examples = [];
|
||||
const exListItems = block.querySelectorAll('.termlist-item-examples li');
|
||||
exListItems.forEach(li => {
|
||||
// Ignore the audio button text (usually inside span elements)
|
||||
const text = Array.from(li.childNodes)
|
||||
.filter(node => node.nodeType === Node.TEXT_NODE)
|
||||
.map(node => node.textContent.trim())
|
||||
.join(' ')
|
||||
.trim();
|
||||
if (text) examples.push(text);
|
||||
});
|
||||
|
||||
// Image
|
||||
let imageUrl = "";
|
||||
const img = block.querySelector('.termlist-item-images img');
|
||||
if (img) {
|
||||
imageUrl = img.getAttribute('data-src') || img.src;
|
||||
if (imageUrl && imageUrl.startsWith('/')) {
|
||||
imageUrl = window.location.origin + imageUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Audio (UK and US)
|
||||
let ukAudio = "";
|
||||
let usAudio = "";
|
||||
|
||||
// The structure is usually <audio><source src="...">
|
||||
const audioSpans = block.querySelectorAll('.jq-audio-player audio');
|
||||
audioSpans.forEach(audio => {
|
||||
const source = audio.querySelector('source');
|
||||
if (source) {
|
||||
let src = source.getAttribute('src');
|
||||
if (src && src.startsWith('/')) {
|
||||
src = window.location.origin + src;
|
||||
}
|
||||
if (src && src.includes('lang=en-GB')) {
|
||||
ukAudio = src;
|
||||
} else if (src && src.includes('lang=en-US')) {
|
||||
usAudio = src;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (word) {
|
||||
items.push({
|
||||
word: word,
|
||||
type: type,
|
||||
pronunciation: pronunciation,
|
||||
definition: definition,
|
||||
examples: examples,
|
||||
imageUrl: imageUrl,
|
||||
audio: {
|
||||
uk: ukAudio,
|
||||
us: usAudio
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
// Try to extract from the main document first
|
||||
let items = extractData(document);
|
||||
|
||||
// If none found, see if there's an iframe (like on the lesson page)
|
||||
if (items.length === 0) {
|
||||
try {
|
||||
const iframe = document.querySelector('iframe.learncourse-iframe');
|
||||
if (iframe && iframe.contentDocument) {
|
||||
items = extractData(iframe.contentDocument);
|
||||
}
|
||||
} catch (e) {
|
||||
// Might fail due to cross-origin if running locally without properly configured URLs,
|
||||
// but on study4.com it should work.
|
||||
console.error("Cannot access iframe content:", e);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
})();
|
||||
Reference in New Issue
Block a user