最近,我的一个朋友在讯网教育平台上刷课时遇到了问题。他抱怨说平台经常弹出题目窗口,导致视频暂停,而且一个课程就有上千分钟。更糟糕的是,平台还有人脸检测功能,如果检测不到人脸也会弹出窗口。似乎网络上也没有这个平台的刷题脚本。因此,我就简单地为他编写了一个脚本,让他可以放心地去做其他事情。
简单分析了网页的结构,然后利用专业知识根据遇到的问题使用油猴插件来编写脚本,以满足各功能需求。
什么是油猴
一款广受欢迎的浏览器扩展(插件),主要用于管理和运行用户脚本(UserScript)。用户脚本是一种可以对网页进行自定义操作的小型JavaScript程序,通过这些脚本,可以改变网页的外观、行为,甚至自动化一些操作。
具体代码与功能
功能1:绕过人脸检测
定位到人脸检测的弹窗标签,最初需要进行检测才能开始课程学习。因此,我们跳过首次检测,而在后续该标签再次出现时,一旦自动检测到,我们便将其删除。
let faceRecognitionHandled = false; // 用于标记人脸识别是否已经处理
// 删除指定标签
function removeFaceRecognitionBox() {
return new Promise((resolve) => {
const faceBox = document.querySelector('.el-message-box');
if (faceBox) {
faceBox.remove();
resolve('Face recognition box removed');
} else {
resolve('No face recognition box found');
}
});
}
// MutationObserver 监测标签的出现
function observeFaceRecognitionBox() {
const observer = new MutationObserver(async (mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.addedNodes.length > 0 && !faceRecognitionHandled) {
faceRecognitionHandled = true;
console.log('Face recognition box appeared');
await removeFaceRecognitionBox();
observer.disconnect(); // 完成后停止观察
} else if (mutation.addedNodes.length > 0 && faceRecognitionHandled) {
console.log('Face recognition box reappeared and will be removed');
await removeFaceRecognitionBox();
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
// 启动观察器
observeFaceRecognitionBox();
功能2:本集自动答题,并继续视频播放
关键点:获取所有选项及确认框,模拟点击,并监听ended事件以判断是否结束,从而灵活地调用下一个函数。
// 自动答题并播放视频
function AutoPlayVideo() {
let options = document.querySelectorAll('.choice .li');
if (options.length > 0) {
options[0].click();
const submitButton = document.querySelector('.bottoms .el-button--primary');
if (submitButton) {
submitButton.click();
const video = document.querySelector('video');
if (video) {
video.play();
video.addEventListener('ended', playNextVideo);
}
} else {
console.log('not found button');
}
} else {
console.log('not found option');
}
}
功能3:续集的自动播放
关键点:通过唯一标识"play"类名确定当前播放视频在总视频数数组中的位置,当检测到视频播放结束时,模拟点击下一个视频,然后持续进行监听。
function playNextVideo() {
let nextEpisodes = document.querySelectorAll('ul[data-v-5b74de8d] > li.pointer');
const currentVideoIndex = Array.from(nextEpisodes).findIndex(li => li.classList.contains('play'));
if (currentVideoIndex !== -1 && currentVideoIndex < nextEpisodes.length - 1) {
nextEpisodes[currentVideoIndex + 1].click();
const video = document.querySelector('video');
if (video) {
video.play();
video.addEventListener('ended', playNextVideo);
}
}
}
在函数的最后,我们设置了一个计时器,每隔1秒就会检测一次整个网页,以便进行重复的操作。
setInterval(AutoPlayVideo, 1000);
这是一个简单而实用的脚本,非常有趣。它是基于真实需求的,并且后面也许还可以增加了一些额外功能:例如倍速播放,或者使用预录制的视频流来替代实时摄像,这样就无需遮挡摄像头了。哈哈。