您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
优学院视频刷课脚本
// ==UserScript== // @name FuckUlearning // @description 优学院视频刷课脚本 // @version 1.0.1 // @author Nanashi // @match *://ua.ulearning.cn/* // @icon https://raw.githubusercontent.com/Nanashi-Development/FuckULearning/main/logo.jpg // @supportURL https://github.com/Nanashi-Development/FuckULearning/issues // @homepageURL https://github.com/Nanashi-Development/FuckULearning // @grant none // @namespace https://gf.qytechs.cn/users/1518317 // ==/UserScript== // 等待函数 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 等待指定元素加载完成 async function waitForElement(selector, timeout = 10000) { const startTime = Date.now(); while (Date.now() - startTime < timeout) { const element = document.querySelector(selector); if (element) { return element; // 元素已加载,返回该元素 } await sleep(500); // 每隔 500 毫秒检查一次 } console.log(`等待元素超时:${selector}`); return null; // 超时未找到元素 } // 判断是否是视频课程 function is_video_course() { const playButton = document.querySelector('div.mejs__overlay-button[role="button"][aria-label="播放"]'); const isVideo = !!playButton; console.log(isVideo ? '检测到视频课程' : '未检测到视频课程'); return isVideo; } // 自动检测页面中的视频播放器并逐个播放 async function playAllVideos() { // 获取所有 class="video-element" 的元素 const videoElements = document.querySelectorAll('.video-element'); // 遍历每个 video-element for (let i = 0; i < videoElements.length; i++) { const videoElement = videoElements[i]; // 定位 <div class="mejs__container"> 并获取其 id const container = videoElement.querySelector('.mejs__container'); const videoId = container ? container.id : null; // 如果找到容器,则获取其 id,否则为 null if (!videoId) { console.log('未找到视频容器的 id,跳过当前视频'); continue; } console.log(`当前视频的 videoId:${videoId}`); // 判断视频是否已经看过了 const videoInfo = videoElement.querySelector('.video-info'); if (videoInfo) { const finishedSpan = videoInfo.querySelector('span[data-bind="text: $root.i18nMessageText().finished"]'); if (finishedSpan) { console.log(`视频已看完,视频ID:${videoId}`); continue; } else { console.log(`视频未看完,视频ID:${videoId}`); } } else { console.log(`未找到 video-info 元素,以未看完模式继续,视频ID:${videoId}`); } // 未看过的视频,进行观看 const playButtonSelector = `#${videoId} .mejs__overlay-button[aria-label="播放"]`; const playButton = await waitForElement(playButtonSelector, 5000); const realVideoElement = document.querySelector(`#${videoId} video`); if (playButton) { const isVisible = window.getComputedStyle(playButton).display !== 'none'; if (isVisible) { playButton.click(); console.log(`已点击播放按钮,开始播放视频:${videoId}`); // 点击二倍速播放按钮 try { await sleep(1000); // 等待播放器加载 const speedButton = document.querySelector(`#${videoId} label.mejs__speed-selector-label.mejs__speed-selected`); if (speedButton && speedButton.textContent === '2.00x') { console.log(`当前已是二倍速播放:${videoId}`); } else { // 如果当前不是2倍速,尝试寻找并点击2倍速选项 const speedSelector = document.querySelector(`#${videoId} .mejs__speed-selector`); if (speedSelector) { const allSpeedOptions = speedSelector.querySelectorAll('label.mejs__speed-selector-label'); for (const option of allSpeedOptions) { if (option.textContent.trim() === '2.00x') { option.click(); console.log(`已切换到二倍速播放:${videoId}`); break; } } } else { console.log(`未找到速度选择器,使用默认播放速度:${videoId}`); } } } catch (error) { console.log(`设置播放速度时出错:${videoId},错误:${error.message}`); } // 等待视频播放完成 let isFinished = false; while (!isFinished) { // 是否出现暂停弹窗 await sleep(1000); needRepaly = handle_modal( 'span[data-bind="text: $root.i18nMsgText().walkingTooLong"]', () => document.querySelector('button.btn-submit[data-bind="text: $root.i18nMsgText().continueStudy"]')?.click(), '暂停弹窗已存在,点击继续学习按钮' ); await sleep(1000); if (needRepaly) { playButton.click(); console.log(`已重新开始播放视频:${videoId}`); } // 检查视频是否播放完成 await sleep(1000); console.log(`视频状态: currentTime=${realVideoElement.currentTime}, duration=${realVideoElement.duration}, ended=${realVideoElement.ended}`); if (realVideoElement.ended || realVideoElement.currentTime >= realVideoElement.duration - 1 || realVideoElement.currentTime === 0) { console.log(`视频 ${videoId} 播放完成`); isFinished = true; break; } console.log(`视频 ${videoId} 未播放完成,继续等待...`); } } else { console.log(`播放按钮不可见,无法播放视频:${videoId}`); } } else { console.log(`未找到播放按钮,跳过视频:${videoId}`); } } console.log('本页面所有视频播放完成'); } // 弹窗处理函数 function handle_modal(selector, action, logMessage) { const modalElement = document.querySelector(selector); if (modalElement && modalElement.offsetParent !== null) { console.log(logMessage); action(); return true; } return false; } // 点击下一页按钮&检查是否完成 async function goto_next_page_and_check_finish() { const nextPageButton = document.querySelector('.btn-tip span[data-bind="text: i18nMessageText().nextPage"]'); if (nextPageButton) { nextPageButton.click(); console.log('已点击下一页按钮'); } else { console.log('未找到下一页按钮'); } await sleep(1000); // 处理未完成测试题目弹窗 handle_modal( 'span[data-bind="text: $root.i18nMsgText().questionsNotCompleted"]', () => document.querySelector('button.btn-hollow[data-bind="text: $root.i18nMsgText().confirmLeave"]')?.click(), '未完成题目弹窗已存在,点击确定离开按钮' ); await sleep(1000); // 处理未完成章节内容弹窗 handle_modal( 'span[data-bind="text: i18nMessageText().incompleteChapter"]', () => document.querySelector('button.btn-hollow[data-bind="click: goNextPage"]')?.click(), '未完成章节内容弹窗已存在,点击继续下一章按钮' ); await sleep(1000); // 处理未完成章节内容2弹窗 const isFinished = handle_modal( 'span[data-bind="text: i18nMessageText().incompleteChapter2"]', () => document.querySelector('button.btn-hollow[data-bind="click: closeStatPage"]')?.click(), '未完成章节内容2弹窗已存在,点击关闭按钮' ); return isFinished; // 返回是否完成 } // 创建可视化弹窗 function createControlPanel() { const panel = document.createElement('div'); panel.id = 'control-panel'; panel.style.position = 'fixed'; panel.style.top = '50px'; panel.style.left = '50px'; panel.style.width = '300px'; panel.style.height = '300px'; panel.style.backgroundColor = '#f9f9f9'; panel.style.border = '1px solid #ccc'; panel.style.borderRadius = '8px'; panel.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; panel.style.zIndex = '9999'; panel.style.resize = 'both'; panel.style.overflow = 'hidden'; // 隐藏溢出内容 panel.style.padding = '10px'; // 添加标题 const title = document.createElement('div'); title.innerText = '刷课控制面板'; title.style.fontSize = '16px'; title.style.fontWeight = 'bold'; title.style.marginBottom = '10px'; title.style.cursor = 'move'; panel.appendChild(title); // 添加启动按钮 const startButton = document.createElement('button'); startButton.innerText = '启动'; startButton.style.marginRight = '10px'; startButton.onclick = async () => { logMessage('启动刷课程序...'); await main(); // 调用主程序 }; panel.appendChild(startButton); // 添加停止按钮 const stopButton = document.createElement('button'); stopButton.innerText = '停止'; stopButton.onclick = () => { logMessage('停止刷课程序...'); location.reload(); // 刷新页面以停止程序 }; panel.appendChild(stopButton); // 添加日志显示区域 const logContainer = document.createElement('div'); logContainer.id = 'log-container'; logContainer.style.marginTop = '10px'; logContainer.style.height = 'calc(100% - 80px)'; // 自适应高度,减去标题和按钮的高度 logContainer.style.overflowY = 'auto'; logContainer.style.backgroundColor = '#fff'; logContainer.style.border = '1px solid #ddd'; logContainer.style.padding = '5px'; logContainer.style.fontSize = '12px'; logContainer.style.color = '#333'; panel.appendChild(logContainer); // 添加拖动功能 let isDragging = false; let offsetX, offsetY; title.onmousedown = (e) => { isDragging = true; offsetX = e.clientX - panel.offsetLeft; offsetY = e.clientY - panel.offsetTop; document.onmousemove = (e) => { if (isDragging) { panel.style.left = `${e.clientX - offsetX}px`; panel.style.top = `${e.clientY - offsetY}px`; } }; document.onmouseup = () => { isDragging = false; document.onmousemove = null; document.onmouseup = null; }; }; // 将弹窗添加到页面 document.body.appendChild(panel); } // 日志记录函数 function logMessage(message) { const logContainer = document.getElementById('log-container'); if (logContainer) { const logEntry = document.createElement('div'); logEntry.innerText = `[${new Date().toLocaleTimeString()}] ${message}`; logContainer.appendChild(logEntry); logContainer.scrollTop = logContainer.scrollHeight; // 自动滚动到底部 } } // 主程序 async function main() { logMessage('刷课程序启动...'); let allFinished = false; while (!allFinished) { if (is_video_course()) { logMessage('检测到视频课程,准备播放所有视频...'); await playAllVideos(); // 播放所有视频 logMessage('本页面所有视频播放完成,准备进入下一页...'); allFinished = await goto_next_page_and_check_finish(); } else { logMessage('检测到非视频课程,准备进入下一页...'); await sleep(1000); allFinished = await goto_next_page_and_check_finish(); } } logMessage('刷课程序执行完毕'); } // 调用函数创建控制面板 createControlPanel();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址