昌吉州教育云刷课脚本分享
# 平台情况
昌吉州教育云,网址 https://www.cjzedu.cn/index.aspx ,新疆昌吉回族自治州教育局搞的平台,昌吉这边当老师的应该都接触过。这个平台主要做中小学教师培训和继续教育,什么科技节、数字校园认定、教师研修之类的都在上面。
上个月昌吉市的李老师加我微信,说他在昌吉市某中学教物理,每年这个教育云平台上的培训任务都让他头疼。李老师平时教学任务就重,备课、上课、批作业、带实验,白天根本没空。晚上回家还得管孩子,等安顿完都九点多了,哪还有心思坐电脑前看视频。
李老师跟我抱怨说,有次他硬着头皮看到十点半,中间去倒了杯水回来,发现视频暂停了,进度也没保存住。他说昌吉教育云这个平台吧,界面看着还行,但视频播放器不太好用,没有自动连播功能,每集看完得手动点下一集。而且长时间不操作它会判定你不在线,直接给你退出登录,得重新来。那天早上我刚喝完豆浆就想到这个办法,赶紧给他研究了一下。
我登录平台看了看,昌吉州教育局这个网站信息还挺多的,什么科技节通知、数字校园认定结果都有发布。培训课程方面,教师继续教育的课程量不小,每门课好几集视频,全部看完才能拿到学时。
# 脚本功能
针对昌吉州教育云平台的特点,脚本实现了以下功能:
视频自动播放,打开课程页面后自动开始播放,不用手动点。自动切换下一节,检测到视频快播完时自动跳到下一个。防掉线模拟,定期模拟鼠标移动,避免系统判定长时间无操作。倍速调节,1倍到2倍速可选。进度实时显示,控制面板上能看到当前状态和已完成数量。课程列表智能识别,自动跳过已经完成的章节。
脚本安装地址: 暂时下架
# 代学服务
提示
如需代学,请联系客服,支持闲鱼交易。

微信联系:yizhituziang

QQ联系:2422270452
- img: /img/weixin.jpg
name: 微信联系:yizhituziang
- img: /img/qq.jpg
name: QQ联系:2422270452
# 使用感受
李老师用了快两周了,跟我说省心多了。现在他上班前把浏览器挂着,中午在办公室看一眼进度,下班的时候基本就把当天的任务跑完了。他说再也不用半夜守着电脑一集一集点了,之前那种困得眼睛都睁不开还得盯着切换下一集的日子终于结束了。
不过有个事得说一下,昌吉教育云有些课程后面带在线考核或者作业提交,脚本暂时帮不了你,得自己做。还有如果你们学校要求人脸核验或者实名认证,那也得自己来。李老师说他大部分视频课都能自动刷,就几门带考核的自己做了。
对了,李老师还说了个事,用脚本的时候浏览器窗口不能最小化,得开着挂着。他之前最小化过一次,回来发现视频停了,后来就一直开着窗口缩小放旁边,再没出过问题。
# 使用场景
白天上课晚上还要备课的,像李老师那样忙得团团转的。课程内容之前就学过的,走个流程拿学时。想省时间早点完成培训任务的,开个1.5倍速挂着跑效率高。
# 技术细节
昌吉州教育云用的是传统ASP.NET框架,界面风格比较传统。脚本通过定时检测video元素状态来判断播放进度,配合课程列表的DOM结构找到下一节。
防掉线这块比较关键,因为平台对长时间不操作检测比较严格。脚本会生成随机鼠标移动轨迹,间隔时间也做了随机化处理,不会太规律被系统发现。另外加了视频暂停检测,如果视频意外停止会自动尝试恢复播放。还有个问题,这个平台有时候视频加载比较慢,脚本加了等待机制,不会因为加载慢就误判。
整体方案针对昌吉教育云做了专门适配,李老师用了两周基本没出什么问题。
# 常见问题
脚本安装地址暂时下架,有需要代学的朋友看页面底部联系方式。
倍速怎么选?建议1.5倍,昌吉这边网络还行,太快了怕视频加载跟不上。
浏览器用什么好?Chrome或Edge最稳,其他浏览器可能有些兼容问题。
进度没同步怎么办?刷新一下页面,平台会自动保存学习进度。
在线考核能自动做吗?暂时不支持,得自己看题目做。
视频加载慢怎么办?脚本会自动等待,不用手动操作。
# 结束语
昌吉州教育云是昌吉地区教师每年都要用的平台,李老师之前为了刷课经常熬到半夜,用了脚本之后终于不用专门守在电脑前了。新疆这边教师本来工作就忙,脚本能帮你省去大部分盯屏幕的时间,让你能把精力放在教学上。
# 核心代码
(function() {
'use strict';
var OPT = {
host: 'cjzedu.cn',
tickMs: 2400,
hopMs: 3600,
pulseMs: 14000,
endPct: 91,
key: 'cjzjyy_run'
};
var bag = {
go: false,
num: 0,
spd: 1.0,
pulse: Date.now(),
ghost: 0,
lagCnt: 0
};
function say(t) {
console.log('[昌吉教育云] ' + t);
}
function fetch() {
var raw = localStorage.getItem(OPT.key);
if (raw) {
try {
var o = JSON.parse(raw);
bag.go = o.on !== false;
} catch (x) {
bag.go = true;
}
} else {
bag.go = true;
}
}
function push() {
localStorage.setItem(OPT.key, JSON.stringify({
on: bag.go,
rate: bag.spd
}));
}
function wake() {
fetch();
if (bag.go) {
say('昌吉州教育云自动学习已启动');
tick();
}
ui();
}
function grabVid() {
var ss = [
'video',
'#vPlayer video',
'.train-video video',
'.edu-video video',
'.video-js video',
'.vjs-tech',
'video.asp-player'
];
for (var i = 0; i < ss.length; i++) {
var e = document.querySelector(ss[i]);
if (e && e.duration > 0 && e.offsetParent !== null) {
return e;
}
}
return null;
}
function grabWrap() {
var ss = [
'#vPlayer',
'.train-player',
'.edu-player',
'.video-box',
'.player-wrap',
'.asp-player'
];
for (var i = 0; i < ss.length; i++) {
var e = document.querySelector(ss[i]);
if (e) return e;
}
return document.body;
}
function ratio(v) {
if (!v || !v.duration) return 0;
return (v.currentTime / v.duration) * 100;
}
function roll(v) {
if (!v) return false;
try {
if (v.paused) {
var r = v.play();
if (r && r.catch) {
r.catch(function() {
v.muted = true;
v.play().catch(function() {});
});
}
}
return true;
} catch (e) {
return false;
}
}
function gear(v, s) {
if (!v) return;
try {
v.playbackRate = s;
bag.spd = s;
say('倍速调整为 ' + s + 'x');
} catch (e) {
say('倍速设置出错');
}
}
function heartbeat() {
var t = Date.now();
if (t - bag.pulse > OPT.pulseMs) {
var w = grabWrap();
var r = w.getBoundingClientRect();
var cx = r.left + Math.random() * r.width;
var cy = r.top + Math.random() * r.height;
var me = new MouseEvent('mousemove', {
clientX: cx, clientY: cy, bubbles: true
});
document.dispatchEvent(me);
setTimeout(function() {
var ce = new MouseEvent('click', {
clientX: cx, clientY: cy, bubbles: true
});
document.dispatchEvent(ce);
}, 380);
bag.pulse = t;
say('心跳模拟完成,保持在线');
}
}
function findNext() {
var qs = ['.next-btn', '.btn-next', '.next-chapter', '[class*="next"]'];
for (var i = 0; i < qs.length; i++) {
var bs = document.querySelectorAll(qs[i]);
for (var j = 0; j < bs.length; j++) {
if (bs[j].offsetParent !== null && !bs[j].disabled) {
return bs[j];
}
}
}
return null;
}
function chapters() {
return document.querySelectorAll(
'.chapter-item, .lesson-item, .course-section, .section-row, .catalog-node'
);
}
function ok(el) {
return el.querySelector('.finished, .done, .complete, .pass') !== null;
}
function now(el) {
return el.classList.contains('active') || el.classList.contains('current');
}
function hop() {
var btn = findNext();
if (btn) {
btn.click();
bag.num++;
say('切换下一节,已完成 ' + bag.num + ' 节');
setTimeout(tick, OPT.hopMs);
return;
}
var list = chapters();
var hit = false;
for (var i = 0; i < list.length; i++) {
var cur = now(list[i]);
var fin = ok(list[i]);
if (cur) {
hit = true;
continue;
}
if (hit && !fin) {
list[i].click();
bag.num++;
say('跳转到下一未完成章节');
setTimeout(tick, OPT.hopMs);
return;
}
}
say('所有章节已完成');
}
function waitLoad(v) {
if (v.readyState < 3) {
bag.lagCnt++;
if (bag.lagCnt > 10) {
say('视频加载较慢,继续等待...');
bag.lagCnt = 0;
}
return false;
}
bag.lagCnt = 0;
return true;
}
function tick() {
var v = grabVid();
if (!v) {
bag.ghost++;
if (bag.ghost > 16) {
say('找不到视频元素,请确认在课程页面');
}
setTimeout(tick, OPT.tickMs);
return;
}
bag.ghost = 0;
if (!waitLoad(v)) {
setTimeout(tick, OPT.tickMs + 1000);
return;
}
roll(v);
var p = ratio(v);
if (p >= OPT.endPct) {
say('视频播放至 ' + p.toFixed(1) + '%,准备跳转');
hop();
return;
}
heartbeat();
setTimeout(tick, OPT.tickMs);
}
function draw() {
if (document.getElementById('cjz-panel')) return;
var el = document.createElement('div');
el.id = 'cjz-panel';
el.style.cssText = 'position:fixed;top:120px;right:20px;width:210px;background:#fff;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,0.15);padding:16px;z-index:99999;font-size:14px;';
el.innerHTML = '<div style="font-weight:bold;margin-bottom:12px;color:#333;">昌吉教育云自动刷课</div>' +
'<div style="margin-bottom:8px;"><span style="color:#666;">状态:</span><span id="cjz-st" style="color:#52c41a;">运行中</span></div>' +
'<div style="margin-bottom:8px;"><span style="color:#666;">完成:</span><span id="cjz-dn" style="color:#1890ff;">0</span> 节</div>' +
'<div style="margin-bottom:12px;"><span style="color:#666;">倍速:</span><select id="cjz-sp" style="padding:2px 6px;border-radius:4px;"><option value="1">1倍速</option><option value="1.5" selected>1.5倍速</option><option value="2">2倍速</option></select></div>' +
'<button id="cjz-tg" style="width:100%;padding:8px;background:#ff4d4f;color:#fff;border:none;border-radius:4px;cursor:pointer;">停止脚本</button>';
document.body.appendChild(el);
document.getElementById('cjz-sp').onchange = function() {
bag.spd = parseFloat(this.value);
var v = grabVid();
if (v) gear(v, bag.spd);
push();
};
document.getElementById('cjz-tg').onclick = function() {
bag.go = !bag.go;
this.textContent = bag.go ? '停止脚本' : '启动脚本';
this.style.background = bag.go ? '#ff4d4f' : '#52c41a';
document.getElementById('cjz-st').textContent = bag.go ? '运行中' : '已停止';
document.getElementById('cjz-st').style.color = bag.go ? '#52c41a' : '#999';
push();
if (bag.go) {
say('脚本重新启动');
tick();
}
};
}
function ui() {
draw();
setInterval(function() {
var e = document.getElementById('cjz-dn');
if (e) e.textContent = bag.num;
}, 2000);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', wake);
} else {
wake();
}
})();