吉林省中盛佳源专技培训网刷课脚本分享
# 平台情况
吉林省中盛佳源专技培训网,网址 https://jlzj.ylxue.net/ ,吉林这边做专业技术人员培训的应该都接触过。这个平台覆盖面还挺广的,公需课专业课都有,什么发展工业互联网、深入学习二十大精神、压力与情绪管理之类的课程。
上周长春的刘姐找我,说她在中盛佳源上刷课快刷崩溃了。刘姐在长春一家设计院做结构设计,平时项目赶工期的时候天天加班到九十点,回家还得开电脑看那些继续教育视频。她说登录账号就是身份证号,密码是ylx加身份证后六位,这个倒是方便,但视频是真的磨人。
刘姐跟我吐槽说,有些课内容其实挺好的,像那个压力与情绪管理,她挺想认真看看的。但问题是时间不允许啊,单位要求月底之前必须完成多少学时,她哪有那个闲工夫一节一节慢慢看。而且这个平台的视频播放器有点奇怪,进度条总是卡,有时候拖拽进度条还不好使。
我登上去看了看,界面做得还行,课程分类有公需课和专业课两大块。专家团队阵容也不错,有什么数字经济学家、高级会计师、心理咨询师之类的。但视频播完不会自动跳下一节这个问题确实烦人,还有长时间不操作会掉线。
# 脚本功能
提示
如需代学,请联系客服,支持闲鱼交易。

微信联系:yizhituziang

QQ联系:2422270452
- img: /img/weixin.jpg
name: 微信联系:yizhituziang
- img: /img/qq.jpg
name: QQ联系:2422270452
针对吉林省中盛佳源专技培训网的特点,脚本实现了以下功能:
视频自动播放,进入课程页面后自动开始,不用手动点播放按钮。自动切换下一节,检测到视频快播完时自动跳到下一个章节。防掉线模拟,定期模拟鼠标移动和点击,避免系统判定无操作。倍速调节,1倍到2倍速可选。进度实时显示,控制面板上能看到当前状态和已完成数量。课程目录智能识别,自动跳过已经完成的章节。
脚本安装地址: 暂时下架
# 使用感受
刘姐用了差不多十天了,她说整体体验比之前好太多了。现在她每天上班前打开浏览器挂着,中午吃饭的时候看一眼进度条,基本不用怎么管。控制面板在右侧,运行状态、完成数量、倍速都显示得清楚。
不过有个事得提醒一下,中盛佳源有些专业课带课后测验,这个脚本帮不了,得自己做。还有如果你们单位要求人脸验证或者实名认证确认,那也得自己来。刘姐说她公需课基本都能自动刷,专业课有几门带测验的就自己做了。
对了,刘姐还提到一个细节,她说有时候视频会突然卡住不动,这种情况脚本会自动检测并尝试重新播放。如果实在卡住了刷新一下页面就行,脚本会从上次的位置继续。
# 使用场景
工作忙没时间盯屏幕的,像刘姐那样项目赶工期天天加班的。课程内容之前接触过的,走流程拿学时的。想省心省力的,挂着脚本自动跑,自己该干嘛干嘛。
# 技术细节
中盛佳源用的是ylxue系列的通用框架,播放器兼容性还行但偶尔有卡顿。脚本通过定时检测video元素状态来判断播放进度,配合课程列表DOM结构找到下一节。
防掉线这块比较重要,因为吉林这个平台对长时间不操作检测比较严格。脚本会生成随机鼠标移动轨迹,间隔时间也做了随机化处理,不会太规律。
整体方案针对中盛佳源平台做了专门适配,刘姐用了十天没出过什么大问题。
# 常见问题
脚本安装地址暂时下架,有需要代学的朋友看页面底部联系方式。
倍速怎么选?建议1.5倍,吉林这边网络质量还行,但太快了怕视频加载跟不上。
浏览器用什么好?Chrome或Edge最稳,其他浏览器可能兼容性问题。
进度不同步怎么办?刷新重试,平台会定时保存学习进度。
课后测验能自动做吗?暂时不支持,得自己看题目做。
# 结束语
吉林省中盛佳源专技培训网是吉林地区专技人员每年都要用的平台,课程种类不少但刷起来确实费时间。刘姐之前为了刷课连着好几天晚上没休息好,用了脚本之后终于不用熬夜了。东北这边冬天本来就冷,坐在电脑前刷课更冷,脚本能帮你省去大部分盯屏幕的时间。
# 核心代码
(function() {
'use strict';
const CFG = {
domain: 'jlzj.ylxue.net',
interval: 2700,
nextWait: 3300,
idleGap: 13000,
donePct: 89,
key: 'jlzj_auto_cfg'
};
let st = {
on: false,
cnt: 0,
spd: 1.0,
lastAct: Date.now(),
errCnt: 0
};
function log(m) {
console.log(`[吉林中盛佳源] ${m}`);
}
function loadCfg() {
const s = localStorage.getItem(CFG.key);
if (s) {
try {
const d = JSON.parse(s);
st.on = d.enabled !== false;
} catch (e) {
st.on = true;
}
} else {
st.on = true;
}
}
function saveCfg() {
localStorage.setItem(CFG.key, JSON.stringify({
enabled: st.on,
spd: st.spd
}));
}
function boot() {
loadCfg();
if (st.on) {
log('吉林省中盛佳源专技培训自动学习已启动');
runCheck();
}
makePanel();
}
function queryVideo() {
const list = [
'video',
'#videoPlayer video',
'.course-video video',
'.play-video video',
'.video-js video',
'.vjs-tech',
'video.prism-player'
];
for (const sel of list) {
const el = document.querySelector(sel);
if (el && el.duration > 0 && el.offsetParent !== null) {
return el;
}
}
return null;
}
function queryWrap() {
const list = [
'#videoPlayer',
'.course-player',
'.play-wrap',
'.video-container',
'.player-wrap',
'.prism-player'
];
for (const sel of list) {
const el = document.querySelector(sel);
if (el) return el;
}
return document.body;
}
function pct(v) {
if (!v || !v.duration) return 0;
return (v.currentTime / v.duration) * 100;
}
function doPlay(v) {
if (!v) return false;
try {
if (v.paused) {
const r = v.play();
if (r && r.catch) {
r.catch(() => {
v.muted = true;
v.play().catch(() => {});
});
}
}
return true;
} catch (e) {
return false;
}
}
function doSpeed(v, s) {
if (!v) return;
try {
v.playbackRate = s;
st.spd = s;
log(`倍速设为 ${s}x`);
} catch (e) {
log('倍速设置失败');
}
}
function fakeAction() {
const now = Date.now();
if (now - st.lastAct > CFG.idleGap) {
const wrap = queryWrap();
const rect = wrap.getBoundingClientRect();
const x = rect.left + Math.random() * rect.width;
const y = rect.top + Math.random() * rect.height;
const mv = new MouseEvent('mousemove', {
clientX: x, clientY: y, bubbles: true
});
document.dispatchEvent(mv);
setTimeout(() => {
const ck = new MouseEvent('click', {
clientX: x, clientY: y, bubbles: true
});
document.dispatchEvent(ck);
}, 500);
st.lastAct = now;
log('模拟操作,防掉线');
}
}
function nextBtn() {
const sels = ['.next-btn', '.btn-next', '.next-chapter', '[class*="next"]'];
for (const sel of sels) {
const btns = document.querySelectorAll(sel);
for (const btn of btns) {
if (btn.offsetParent !== null && !btn.disabled) return btn;
}
}
return null;
}
function courseItems() {
return document.querySelectorAll(
'.course-item, .chapter-item, .lesson-item, .section-item, .catalog-item'
);
}
function isDone(item) {
return item.querySelector('.status-done, .finished, .completed, .done-icon') !== null;
}
function isCur(item) {
return item.classList.contains('active') || item.classList.contains('current');
}
function jumpNext() {
const btn = nextBtn();
if (btn) {
btn.click();
st.cnt++;
log(`点击下一节,已完成 ${st.cnt} 节`);
setTimeout(runCheck, CFG.nextWait);
return;
}
const items = courseItems();
let found = false;
for (const item of items) {
const done = isDone(item);
const cur = isCur(item);
if (cur) { found = true; continue; }
if (found && !done) {
item.click();
st.cnt++;
log('跳到下一未完成章节');
setTimeout(runCheck, CFG.nextWait);
return;
}
}
log('全部完成或无更多课程');
}
function tick() {
const v = queryVideo();
if (!v) {
st.errCnt++;
if (st.errCnt > 25) {
log('多次未找到视频,请检查页面');
return;
}
setTimeout(tick, CFG.interval);
return;
}
st.errCnt = 0;
if (v.paused && st.on) doPlay(v);
const p = pct(v);
if (p >= CFG.donePct || v.ended) {
log(`进度 ${p.toFixed(1)}%,准备切换`);
jumpNext();
return;
}
fakeAction();
setTimeout(tick, CFG.interval);
}
function runCheck() {
if (!st.on) return;
setTimeout(tick, 2000);
}
function stopIt() {
st.on = false;
saveCfg();
log('已暂停');
updPanel();
}
function startIt() {
st.on = true;
saveCfg();
log('已恢复');
runCheck();
updPanel();
}
function toggleIt() {
st.on ? stopIt() : startIt();
}
function changeSpd(s) {
const v = queryVideo();
if (v) doSpeed(v, s);
st.spd = s;
updPanel();
}
function updPanel() {
const a = document.getElementById('jlzj_st');
const b = document.getElementById('jlzj_ct');
const c = document.getElementById('jlzj_sp');
if (a) a.textContent = st.on ? '运行中' : '已暂停';
if (b) b.textContent = st.cnt;
if (c) c.textContent = st.spd;
}
function makePanel() {
const old = document.getElementById('jlzj_panel');
if (old) return;
const p = document.createElement('div');
p.id = 'jlzj_panel';
p.style.cssText = `
position:fixed;top:220px;right:20px;
background:linear-gradient(135deg,#1a237e 0%,#3f51b5 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;
`;
p.innerHTML = `
<div style="font-weight:bold;margin-bottom:10px;font-size:14px;">
吉林中盛佳源自动学习
</div>
<div style="margin-bottom:6px;">状态: <span id="jlzj_st">${st.on ? '运行中' : '已暂停'}</span></div>
<div style="margin-bottom:6px;">已完成: <span id="jlzj_ct">${st.cnt}</span> 节</div>
<div style="margin-bottom:10px;">倍速: <span id="jlzj_sp">${st.spd}</span>x</div>
<div style="display:flex;gap:6px;flex-wrap:wrap;">
<button onclick="window.togJlzj()" style="
padding:5px 10px;border:none;border-radius:5px;
cursor:pointer;background:rgba(255,255,255,0.25);
color:#fff;font-size:12px;
">${st.on ? '暂停' : '开始'}</button>
<button onclick="window.spdJlzj(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.spdJlzj(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.spdJlzj(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(p);
window.togJlzj = toggleIt;
window.spdJlzj = changeSpd;
setInterval(updPanel, 1000);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();