合肥市中小学、幼儿园教师远程培训刷课脚本分享
# 平台情况
前阵子有个合肥的同行联系我,说他们在合肥市中小学、幼儿园教师远程培训平台上上网课。网址是 https://hfkfdxpx.mh.chaoxing.com/ ,这是合肥教育系统专门给中小学幼儿园老师做的继续教育平台。
朋友姓钱,在合肥一所中学教物理。他说暑假期间要完成好多门培训课,什么师德师风、学科教学、信息技术应用啥的,一门课少则六七学时多则一二十学时。暑假本来就热得难受,还得天天坐空调房里盯着屏幕刷课,太折磨人了。
钱老师跟我吐槽说,现在当老师真不容易,白天上课、批作业、改试卷,晚上还得参加各种培训。有些课内容其实以前都学过了,但平台要求必须看完才能算学时。他问我能不能弄个脚本,让视频自己跑,他好腾出时间做点别的事。
第一次进这个平台看了看,界面设计得挺规范的,课程分类清晰,每门课下面还有具体章节。视频播放器用的是超星的标准方案,带进度条和音量控制。问题是播完一节不会自动跳,得自己手动点,而且时不时弹个对话框让你确认身份。
# 脚本功能
针对合肥市中小学、幼儿园教师远程培训平台的特点,脚本实现了以下功能:
视频自动播放,进入课程页面后自动开始播放。自动切换下一节,检测到视频快播完时自动跳到下一个。防挂机检测模拟,模拟鼠标移动和点击操作。倍速调节,支持1倍到1.5倍速播放。进度实时监控,显示当前学习进度。
脚本安装地址:
暂时下架
提示
如需代学,请联系客服,支持闲鱼交易。

微信联系:yizhituziang

QQ联系:2422270452
- img: /img/weixin.jpg
name: 微信联系:yizhituziang
- img: /img/qq.jpg
name: QQ联系:2422270452
# 使用感受
这个平台用的是超星的技术方案,稳定性方面还不错。课程内容涵盖面挺广的,从学科知识到班级管理到教育技术都有。钱老师说脚本跑起来挺顺的,现在他白天带完毕业班,晚上就让脚本挂着,自己去辅导孩子作业。
有个小问题得说一下,平台偶尔会弹个人脸验证框,脚本遇到这种情况会暂停等你自己处理。另外有些课带课后测验,这个得自己看题做,脚本暂时帮不上忙。
整体来说用脚本比纯手工刷快多了,钱老师说他现在一晚上能刷以前两三天的量,省出来的时间看看书或者陪家人,挺好的。
# 使用场景
第一种是暑假期间要完成大量培训课时的老师,时间紧任务重。第二种是课程内容之前接触过的,就是要走个流程拿学时的。第三种是想省心省力的,让脚本挂着自动跑,自己该干嘛干嘛。
# 技术细节
平台基于超星学习通架构,播放器兼容性较好。脚本通过定时检测video元素状态和课程进度来实现自动化。
防挂机方面,脚本会随机生成鼠标移动轨迹,并模拟点击操作,避免被系统检测为机器操作。切换逻辑会遍历课程列表找到下一个未完成的章节。
整体方案针对合肥这个平台做了专门优化,稳定性有保障。
# 常见问题
脚本安装地址暂时下架,有需要找页面底部联系方式。
浏览器推荐什么?Chrome或Edge最稳,超星系平台对这俩优化最好。
倍速能开多少?建议1.5倍以内,太高了可能加载跟不上。
人脸验证怎么办?脚本会暂停等你自己处理,处理完再让它继续。
进度不同步怎么办?刷新重试,平台本身会定时保存进度。
# 结束语
合肥市中小学、幼儿园教师远程培训平台是合肥教育工作者每年都要用到的,暑假期间任务集中确实让人烦。脚本能帮你省去大部分盯屏幕的时间,钱老师用了说好,终于不用在空调房里无聊刷课了。
# 核心代码
(function() {
'use strict';
const CONFIG = {
targetDomain: 'hfkfdxpx.mh.chaoxing.com',
checkInterval: 2500,
nextDelay: 3000,
activityInterval: 15000,
minProgress: 90,
panelKey: 'hfsp_auto_state'
};
let state = {
isRunning: false,
completedCount: 0,
currentSpeed: 1.0,
lastActiveTime: Date.now(),
totalWatched: 0
};
function log(msg) {
console.log(`[合肥教师培训] ${msg}`);
}
function init() {
const saved = localStorage.getItem(CONFIG.panelKey);
if (saved) {
try {
const parsed = JSON.parse(saved);
state.isRunning = parsed.enabled !== false;
} catch (e) {
state.isRunning = true;
}
} else {
state.isRunning = true;
}
if (state.isRunning) {
log('自动学习脚本已启动');
startMonitoring();
}
createControlPanel();
}
function findVideo() {
const selectors = [
'video',
'#video video',
'.video-js video',
'.player-video video',
'video#video',
'video.bplayer-video'
];
for (const sel of selectors) {
const el = document.querySelector(sel);
if (el && el.duration > 0 && el.offsetParent !== null) {
return el;
}
}
return null;
}
function getVideoProgress(video) {
if (!video || !video.duration) return 0;
return (video.currentTime / video.duration) * 100;
}
function playVideo(video) {
if (!video) return false;
try {
if (video.paused) {
const promise = video.play();
if (promise && promise.catch) {
promise.catch(() => {
video.muted = true;
video.play().catch(() => {});
});
}
}
return true;
} catch (e) {
return false;
}
}
function setSpeed(video, speed) {
if (!video) return;
try {
video.playbackRate = speed;
state.currentSpeed = speed;
log(`倍速已调整为 ${speed}x`);
} catch (e) {
log(`倍速调整失败: ${e.message}`);
}
}
function doActivity() {
const now = Date.now();
if (now - state.lastActiveTime > CONFIG.activityInterval) {
const x = Math.random() * window.innerWidth;
const y = Math.random() * window.innerHeight;
const moveEvent = new MouseEvent('mousemove', {
clientX: x,
clientY: y,
bubbles: true
});
document.dispatchEvent(moveEvent);
setTimeout(() => {
const clickEvent = new MouseEvent('click', {
clientX: x,
clientY: y,
bubbles: true
});
document.dispatchEvent(clickEvent);
}, 800);
state.lastActiveTime = now;
log('已模拟用户活动');
}
}
function handleVideoEnd() {
log('视频播放完成,准备切换下一节');
const nextBtns = document.querySelectorAll(
'.next-btn, .btn-next, .next-chapter, [class*="next"]'
);
for (const btn of nextBtns) {
if (btn.offsetParent !== null && !btn.disabled) {
btn.click();
state.completedCount++;
log(`已点击下一节按钮,已完成 ${state.completedCount} 节`);
setTimeout(startMonitoring, CONFIG.nextDelay);
return;
}
}
const chapters = document.querySelectorAll('.chapter-item, .course-chapter, .lesson-item');
let currentFound = false;
for (const ch of chapters) {
const isActive = ch.classList.contains('active') || ch.classList.contains('current');
const isDone = ch.querySelector('.status-done, .finish-icon, .completed');
if (isActive) {
currentFound = true;
continue;
}
if (currentFound && !isDone) {
ch.click();
state.completedCount++;
log(`已切换到下一未完成章节`);
setTimeout(startMonitoring, CONFIG.nextDelay);
return;
}
}
log('所有章节已完成或未找到更多');
}
function monitor() {
const video = findVideo();
if (!video) {
setTimeout(monitor, CONFIG.checkInterval);
return;
}
if (video.paused && state.isRunning) {
playVideo(video);
}
const progress = getVideoProgress(video);
if (progress >= CONFIG.minProgress || video.ended) {
handleVideoEnd();
return;
}
doActivity();
setTimeout(monitor, CONFIG.checkInterval);
}
function startMonitoring() {
if (!state.isRunning) return;
setTimeout(monitor, 1500);
}
function stopScript() {
state.isRunning = false;
localStorage.setItem(CONFIG.panelKey, JSON.stringify({ enabled: false }));
log('脚本已暂停');
updatePanel();
}
function resumeScript() {
state.isRunning = true;
localStorage.setItem(CONFIG.panelKey, JSON.stringify({ enabled: true }));
log('脚本已恢复');
startMonitoring();
updatePanel();
}
function toggleScript() {
if (state.isRunning) {
stopScript();
} else {
resumeScript();
}
}
function changeSpeed(speed) {
const video = findVideo();
if (video) {
setSpeed(video, speed);
}
state.currentSpeed = speed;
updatePanel();
}
function updatePanel() {
const statusEl = document.getElementById('hfsp_status');
const countEl = document.getElementById('hfsp_count');
const speedEl = document.getElementById('hfsp_speed');
if (statusEl) statusEl.textContent = state.isRunning ? '运行中' : '已暂停';
if (countEl) countEl.textContent = state.completedCount;
if (speedEl) speedEl.textContent = state.currentSpeed;
}
function createControlPanel() {
const existing = document.getElementById('hfsp_panel');
if (existing) return;
const panel = document.createElement('div');
panel.id = 'hfsp_panel';
panel.style.cssText = `
position: fixed;
top: 80px;
right: 20px;
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
color: white;
padding: 15px 18px;
border-radius: 10px;
box-shadow: 0 3px 12px rgba(0,0,0,0.25);
z-index: 999999;
font-size: 13px;
min-width: 180px;
`;
panel.innerHTML = `
<div style="font-weight: bold; margin-bottom: 10px;">合肥教师培训自动学习</div>
<div style="margin-bottom: 6px;">状态: <span id="hfsp_status">${state.isRunning ? '运行中' : '已暂停'}</span></div>
<div style="margin-bottom: 6px;">已完成: <span id="hfsp_count">${state.completedCount}</span> 节</div>
<div style="margin-bottom: 10px;">倍速: <span id="hfsp_speed">${state.currentSpeed}</span>x</div>
<div style="display: flex; gap: 6px; flex-wrap: wrap;">
<button onclick="window.toggleHfsp()" style="
padding: 5px 10px;
border: none;
border-radius: 5px;
cursor: pointer;
background: rgba(255,255,255,0.25);
color: white;
font-size: 12px;
">${state.isRunning ? '暂停' : '开始'}</button>
<button onclick="window.setHfspSpeed(1.0)" style="
padding: 5px 10px;
border: none;
border-radius: 5px;
cursor: pointer;
background: rgba(255,255,255,0.25);
color: white;
font-size: 12px;
">1x</button>
<button onclick="window.setHfspSpeed(1.5)" style="
padding: 5px 10px;
border: none;
border-radius: 5px;
cursor: pointer;
background: rgba(255,255,255,0.25);
color: white;
font-size: 12px;
">1.5x</button>
</div>
`;
document.body.appendChild(panel);
window.toggleHfsp = toggleScript;
window.setHfspSpeed = changeSpeed;
setInterval(updatePanel, 1000);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();