国家中小学智慧教育平台刷课脚本分享
# 平台情况
国家中小学智慧教育平台,网址 https://basic.smartedu.cn/ ,这个平台名气挺大的,教育部搞的国家级平台。上面内容特别丰富,什么党史学习、宪法法治、师德师风、学科课程、教师研修、家庭教育,覆盖面非常广。
前几天郑州的金老师联系我,说他们学校要求老师在智慧教育平台上完成研修任务。金老师在郑州一所小学教语文,她说平台上的教师研修板块内容其实挺不错的,有通识研修、学科研修、作业命题啥的,但就是视频太多了,每个专题好几个学时,全部刷下来得花不少时间。
金老师跟我吐槽说,她白天上课、批作业、处理班级事务,晚上回家还要辅导自己孩子写作业,哪还有精力坐在电脑前看那些研修视频。有些内容她之前培训的时候已经学过了,但平台要求必须完整观看才能算学时,这就很烦人。她说那天早上刚喝完豆浆就想到找我帮忙,看看有没有什么省事的办法。
我打开这个平台仔细看了看,界面做得确实不错,国家级平台就是不一样,分类清晰、内容丰富。视频播放器也比较流畅,加载速度很快。但问题还是那个——播完不会自动跳下一节,得手动点。而且有些专题视频特别多,一个一个点下来手都酸了。
# 脚本功能
提示
如需代学,请联系客服,支持闲鱼交易。

微信联系:yizhituziang

QQ联系:2422270452
- img: /img/weixin.jpg
name: 微信联系:yizhituziang
- img: /img/qq.jpg
name: QQ联系:2422270452
针对国家中小学智慧教育平台的特点,脚本实现了以下功能:
视频自动播放,进入课程页面后自动开始播放,不用手动点。自动切换下一节,检测到视频快播完时自动跳到下一个。防闲置模拟,定期模拟鼠标移动,避免系统判定长时间无操作。倍速调节,1倍到2倍速可选。进度实时显示,控制面板上能看到当前状态和已完成数量。专题课程智能识别,自动跳过已完成的章节。
脚本安装地址: 暂时下架
# 使用感受
金老师用了差不多一周了,她说比之前纯手动刷好太多了。现在她每天上班前把浏览器打开挂着,课间休息的时候看一眼进度,放学的时候研修任务基本就完成了。控制面板在右侧,运行状态、完成数量、倍速都显示得清楚。
有个事得说一下,智慧教育平台有些研修板块带互动环节或者讨论区,这个脚本帮不了,得自己参与。还有如果你们学校要求提交研修心得或者作业,那也得自己写。金老师说她大部分视频课都能自动刷,就那些需要互动的自己做了。
对了,金老师还提了一个细节,她说这个平台的视频播放器有时候会自动暂停,可能是网络波动导致的。脚本会检测到这种情况并自动恢复播放,不用手动干预。
# 使用场景
白天上课晚上还要研修的老师,像金老师那样忙得没时间看视频的。课程内容之前学过的,走个流程完成研修任务的。想省时间早点完成研修的,开倍速挂着自动跑效率高。
# 技术细节
国家中小学智慧教育平台用的是比较先进的架构,播放器兼容性很好。脚本通过定时检测video元素状态来判断播放进度,配合课程列表DOM结构找到下一节。
防闲置这块,脚本会生成随机鼠标移动轨迹并模拟点击操作,间隔时间做了随机化处理。另外加了视频自动暂停检测,如果视频意外停止会自动恢复播放。
整体方案针对智慧教育平台做了专门适配,金老师用了一周没出过什么问题。
# 常见问题
脚本安装地址暂时下架,有需要代学的朋友看页面底部联系方式。
倍速开多少合适?建议1.5倍,国家级平台服务器好,1.5倍很稳。
浏览器用什么?Chrome或Edge最稳,这个平台对浏览器兼容性要求不高。
进度没记录怎么办?刷新页面,平台会自动保存观看进度。
互动环节能自动完成吗?不行,讨论区和心得提交得自己来。
# 结束语
国家中小学智慧教育平台是教育部搞的国家级平台,内容确实丰富,但研修任务重的时候刷视频还是很费时间的。金老师之前为了完成研修任务连着好几天晚上没休息好,用了脚本之后终于不用熬夜了。当老师本来就很辛苦,脚本能帮你省去大部分盯屏幕的时间。
# 核心代码
(function() {
'use strict';
const OPTS = {
site: 'basic.smartedu.cn',
pollMs: 2500,
skipMs: 3200,
idleMs: 14000,
endPct: 88,
cacheKey: 'smartedu_auto_run'
};
let env = {
active: false,
count: 0,
speed: 1.0,
lastMove: Date.now(),
stallCnt: 0
};
function log(m) {
console.log(`[国家智慧教育] ${m}`);
}
function restore() {
const raw = localStorage.getItem(OPTS.cacheKey);
if (raw) {
try {
const d = JSON.parse(raw);
env.active = d.running !== false;
} catch (e) {
env.active = true;
}
} else {
env.active = true;
}
}
function persist() {
localStorage.setItem(OPTS.cacheKey, JSON.stringify({
running: env.active,
speed: env.speed
}));
}
function init() {
restore();
if (env.active) {
log('国家中小学智慧教育平台自动学习已启动');
pollVideo();
}
renderUI();
}
function seekVideo() {
const sels = [
'video',
'#video-player video',
'.video-container video',
'.course-video video',
'.video-js video',
'.vjs-tech',
'video.smart-player'
];
for (const s of sels) {
const el = document.querySelector(s);
if (el && el.duration > 0 && el.offsetParent !== null) {
return el;
}
}
return null;
}
function seekWrap() {
const sels = [
'#video-player',
'.video-container',
'.course-player',
'.player-wrap',
'.smart-player'
];
for (const s of sels) {
const el = document.querySelector(s);
if (el) return el;
}
return document.body;
}
function ratio(v) {
if (!v || !v.duration) return 0;
return (v.currentTime / v.duration) * 100;
}
function forcePlay(v) {
if (!v) return false;
try {
if (v.paused) {
const p = v.play();
if (p && p.catch) {
p.catch(() => {
v.muted = true;
v.play().catch(() => {});
});
}
}
return true;
} catch (e) {
return false;
}
}
function forceRate(v, r) {
if (!v) return;
try {
v.playbackRate = r;
env.speed = r;
log(`倍速设为 ${r}x`);
} catch (e) {
log('倍速设置失败');
}
}
function fakeMove() {
const now = Date.now();
if (now - env.lastMove > OPTS.idleMs) {
const wrap = seekWrap();
const rect = wrap.getBoundingClientRect();
const x = rect.left + Math.random() * rect.width;
const y = rect.top + Math.random() * rect.height;
document.dispatchEvent(new MouseEvent('mousemove', {
clientX: x, clientY: y, bubbles: true
}));
setTimeout(() => {
document.dispatchEvent(new MouseEvent('click', {
clientX: x, clientY: y, bubbles: true
}));
}, 650);
env.lastMove = now;
log('模拟操作,防闲置');
}
}
function seekNext() {
const sels = ['.next-btn', '.btn-next', '.next-chapter', '[class*="next"]'];
for (const s of sels) {
const btns = document.querySelectorAll(s);
for (const b of btns) {
if (b.offsetParent !== null && !b.disabled) return b;
}
}
return null;
}
function seekItems() {
return document.querySelectorAll(
'.course-item, .chapter-item, .lesson-item, .section-item, .resource-item'
);
}
function isRead(el) {
return el.querySelector('.status-done, .finished, .completed, .done-icon') !== null;
}
function isHere(el) {
return el.classList.contains('active') || el.classList.contains('current');
}
function advance() {
const btn = seekNext();
if (btn) {
btn.click();
env.count++;
log(`点击下一节,已完成 ${env.count} 节`);
setTimeout(pollVideo, OPTS.skipMs);
return;
}
const items = seekItems();
let hit = false;
for (const el of items) {
const read = isRead(el);
const here = isHere(el);
if (here) { hit = true; continue; }
if (hit && !read) {
el.click();
env.count++;
log('跳到下一未完成章节');
setTimeout(pollVideo, OPTS.skipMs);
return;
}
}
log('全部完成或无更多课程');
}
function pollVideo() {
if (!env.active) return;
const v = seekVideo();
if (!v) {
env.stallCnt++;
if (env.stallCnt > 25) {
log('多次未找到视频,请检查页面');
return;
}
setTimeout(pollVideo, OPTS.pollMs);
return;
}
env.stallCnt = 0;
if (v.paused && env.active) forcePlay(v);
const p = ratio(v);
if (p >= OPTS.endPct || v.ended) {
log(`进度 ${p.toFixed(1)}%,准备切换`);
advance();
return;
}
fakeMove();
setTimeout(pollVideo, OPTS.pollMs);
}
function suspend() {
env.active = false;
persist();
log('已暂停');
syncUI();
}
function wakeup() {
env.active = true;
persist();
log('已恢复');
pollVideo();
syncUI();
}
function flip() {
env.active ? suspend() : wakeup();
}
function chgRate(r) {
const v = seekVideo();
if (v) forceRate(v, r);
env.speed = r;
syncUI();
}
function syncUI() {
const a = document.getElementById('se_st');
const b = document.getElementById('se_ct');
const c = document.getElementById('se_sp');
if (a) a.textContent = env.active ? '运行中' : '已暂停';
if (b) b.textContent = env.count;
if (c) c.textContent = env.speed;
}
function renderUI() {
const old = document.getElementById('se_panel');
if (old) return;
const d = document.createElement('div');
d.id = 'se_panel';
d.style.cssText = `
position:fixed;top:120px;right:20px;
background:linear-gradient(135deg,#1565c0 0%,#42a5f5 100%);
color:#fff;padding:14px 16px;border-radius:10px;
box-shadow:0 3px 12px rgba(0,0,0,0.25);
z-index:999999;font-size:13px;min-width:175px;
`;
d.innerHTML = `
<div style="font-weight:bold;margin-bottom:10px;font-size:14px;">
智慧教育自动学习
</div>
<div style="margin-bottom:6px;">状态: <span id="se_st">${env.active ? '运行中' : '已暂停'}</span></div>
<div style="margin-bottom:6px;">已完成: <span id="se_ct">${env.count}</span> 节</div>
<div style="margin-bottom:10px;">倍速: <span id="se_sp">${env.speed}</span>x</div>
<div style="display:flex;gap:6px;flex-wrap:wrap;">
<button onclick="window.togSe()" style="
padding:5px 10px;border:none;border-radius:5px;
cursor:pointer;background:rgba(255,255,255,0.25);
color:#fff;font-size:12px;
">${env.active ? '暂停' : '开始'}</button>
<button onclick="window.spdSe(1.0)" style="
padding:5px 10px;border:none;border-radius:5px;
cursor:pointer;background:rgba(255,255,255,0.25);
color:#fff;font-size:12px;
">1x</button>
<button onclick="window.spdSe(1.5)" style="
padding:5px 10px;border:none;border-radius:5px;
cursor:pointer;background:rgba(255,255,255,0.25);
color:#fff;font-size:12px;
">1.5x</button>
<button onclick="window.spdSe(2.0)" style="
padding:5px 10px;border:none;border-radius:5px;
cursor:pointer;background:rgba(255,255,255,0.25);
color:#fff;font-size:12px;
">2x</button>
</div>
`;
document.body.appendChild(d);
window.togSe = flip;
window.spdSe = chgRate;
setInterval(syncUI, 1000);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();