优学院视频自动提取字幕js脚本
// 用Set存储字幕(自动去重,只保留首次出现的内容)
const captionsSet = new Set();
// 超时计时器ID
let timeoutId = null;
// 监控开关
let isObserving = true;
// 目标标签选择器(class包含"mejs__captions-text"的span)
const targetSelector = 'span[class*="mejs__captions-text"]';
// 处理新字幕(只添加未出现过的内容)
function handleNewCaption(text) {
if (!text) return; // 忽略空文本
// 只有文本未在Set中时,才添加并重置计时器
if (!captionsSet.has(text)) {
captionsSet.add(text);
console.log('新增字幕:', text); // 实时打印新增的字幕
// 重置10秒计时器(只有新内容才触发计时重置)
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
isObserving = false;
observer.disconnect(); // 停止监听
console.log('\n===== 10秒无新字幕,监控结束 =====');
console.log('完整字幕列表:');
// 将Set转换为数组输出(按出现顺序)
console.log(Array.from(captionsSet).join('\n'));
}, 10000);
}
}
// 提取节点文本
function getNodeText(node) {
return node.textContent?.trim() || '';
}
// 初始扫描已有字幕(避免遗漏页面加载时已存在的)
document.querySelectorAll(targetSelector).forEach(node => {
handleNewCaption(getNodeText(node));
});
// 创建DOM变化观察者(监听新增/更新/属性变化)
const observer = new MutationObserver((mutations) => {
if (!isObserving) return;
mutations.forEach(mutation => {
// 1. 处理新增节点
mutation.addedNodes.forEach(node => {
if (node.nodeType !== 1) return; // 只处理元素节点
const targets = node.matches(targetSelector) ? [node] : node.querySelectorAll(targetSelector);
targets.forEach(span => handleNewCaption(getNodeText(span)));
});
// 2. 处理已有节点的文本内容变化
if (mutation.type === 'characterData' && mutation.target.parentNode) {
const parentSpan = mutation.target.parentNode.closest(targetSelector);
if (parentSpan) {
handleNewCaption(getNodeText(parentSpan));
}
}
// 3. 处理节点class属性变化(编号更新时可能伴随文本变化)
if (mutation.type === 'attributes' && mutation.target.matches(targetSelector)) {
handleNewCaption(getNodeText(mutation.target));
}
});
});
// 启动监听(覆盖所有可能的字幕更新场景)
observer.observe(document.body, {
childList: true, // 监听节点新增/删除
subtree: true, // 监听所有后代节点
characterData: true, // 监听文本内容变化
attributes: true, // 监听属性变化(如class编号)
attributeFilter: ['class'] // 只监听class属性(优化性能)
});
console.log('开始监控字幕(自动去重,10秒无新内容输出完整列表)...');

主动结束监听并输出字幕
// 停止DOM监听
if (observer) observer.disconnect();
// 清除自动结束的计时器
if (timeoutId) clearTimeout(timeoutId);
// 标记为已停止
isObserving = false;
// 输出当前所有字幕
console.log('\n===== 手动结束监控 =====');
console.log('完整字幕列表:');
console.log(Array.from(captionsSet).join('\n'));
一旦获得视频脚本,知识复看将会变得简单许多。
可供日常学习使用。
收录于知乎专栏「js逆向实例」· 查看知乎原文