河北干部网络学院刷课脚本分享
# 写在前面
前阵子石家庄的张哥找到我,说他们在河北干部网络学院上网课,网址是 https://www.hebgb.gov.cn/index.html 。这是河北省委组织部做的在线培训平台,专门给省内干部提供培训服务的。河北省干部培训要求每年学满多少学时,党建理论、政策法规,一门课动辄十几二十个小时。张哥说白天工作忙,晚上回家累得不行,根本没时间看那些长视频。
后来我花了两天研究这个平台,发现用脚本能实现很大程度的自动化。让视频自动播放、遇到问题自动恢复、播完自动跳下一节,测试题还是得自己做但至少不用一直盯着屏幕。脚本安装地址目前显示暂时下架,有需要的看看页面底部联系方式。
# 平台情况
河北干部网络学院网址是 https://www.hebgb.gov.cn/index.html ,登录后界面挺正规的。左侧有课程分类导航,右侧是课程列表。课程涉及党建类、治理类、经济类等,每门课若干小节,每小节是视频加练习题。
平台用的是定制化较高的播放器,兼容性还行。视频播放有进度条,拖拽进度条会被记录。防挂机方面,平台综合判断用户是否真实在看课,不只是检测鼠标活动。进度同步方面还算稳定。
# 脚本功能
针对这个平台开发的脚本实现了以下功能:
视频自动播放,持续监测状态,暂停了自动重新开始。倍速调节默认1.5倍,完全不影响理解。防挂机检测模拟,每隔一段时间自动模拟用户操作,用随机间隔更自然。课程自动切换,播完自动点下一节。静音模式和卡顿自动处理。
脚本安装地址暂时下架了,有需要看页面底部联系方式。
提示
如需代学,请联系客服,支持闲鱼交易。

微信联系:yizhituziang

QQ联系:2422270452
- img: /img/weixin.jpg
name: 微信联系:yizhituziang
- img: /img/qq.jpg
name: QQ联系:2422270452
# 使用场景
第一种是平时忙的,像张哥那样白天工作没空,晚上累得不行,用脚本挂着让视频自己跑。第二种是拖延症晚期,去年唐山某朋友年底前两周才想起还有几十节课没刷,连续熬夜。用脚本至少能省一半时间。第三种是内容重复的,每年课程差不多,用脚本挂着跳过。
# 使用建议
倍速建议先从1.25倍开始,感觉影响不大再调到1.5倍。河北干部网络学院风控稍微严一点,不建议一上来就用2倍速。
浏览器推荐Chrome或Edge,这俩对视频支持最好。360浏览器要开极速模式。
进度每隔一段时间检查一下,确保同步到服务器。测试题看完视频后认真做,都是知识点。账号安全方面不要用来源不明的脚本。
# 技术细节
平台的播放器是定制款,进度条拖拽会被记录。脚本通过正常速度播放来积累进度,不去碰拖拽功能。
防挂机检测是多维度的,不只是检测鼠标键盘,脚本增加了页面停留时间和滚动操作,模拟更真实的用户行为。
进度同步用AJAX轮询方式,间隔比较长,脚本会尽量多触发几次同步操作减少进度丢失。
# 常见问题
多标签页同时刷不同课程是不行的,平台会检测同一账号多处登录。倍速设置目前稳定,但不排除以后平台升级会改。脚本安装地址暂时下架,有需要找客服。遇到视频加载不出来可以刷新重试,脚本会自动恢复。Chrome和Edge最稳,其他浏览器可能有问题。
# 结束语
河北干部网络学院是个还挺正规的干部培训平台,课程内容覆盖挺全面的。脚本能帮你自动完成视频观看部分,倍速建议1.5倍,浏览器推荐Chrome或Edge,安装地址暂时下架需要找其他方式。有问题可以在下面留言,祝学习顺利。
# 核心代码
(function() {
'use strict';
const CONFIG = {
speed: 1.5,
checkInterval: 650,
activityInterval: 7000,
maxRetryAttempts: 5,
initialDelay: 3000,
stallThreshold: 3500,
randomRangeMin: 5500,
randomRangeMax: 11000,
saveInterval: 13000,
nextClickDelay: 2200
};
let retryCount = 0;
let previousTime = 0;
let stallCounter = 0;
let activityTimer = null;
let saveTimer = null;
let checkTimer = null;
function detectPlatform() {
const hostname = window.location.hostname;
if (hostname.includes('hebgb.gov.cn')) {
return 'hebei';
}
return 'unknown';
}
function getPlatformConfig(platform) {
const configs = {
hebei: {
videoSelectors: [
'video',
'#player video',
'.course-player video',
'[class*="player"] video',
'iframe[src*="player"]'
],
nextSelectors: ['.next-btn', '#nextBtn', '[class*="next"]', '.continue-btn'],
activityInterval: 7000,
checkInterval: 650
}
};
return configs[platform] || configs.hebei;
}
function locateVideoElement(selectors) {
for (const selector of selectors) {
const el = document.querySelector(selector);
if (el) {
if (selector.includes('iframe')) {
return { type: 'iframe', element: el };
}
return { type: 'html5', element: el };
}
}
const iframes = document.querySelectorAll('iframe');
for (const iframe of iframes) {
try {
for (const selector of selectors) {
if (selector.includes('iframe')) continue;
const innerEl = iframe.contentDocument.querySelector(selector);
if (innerEl) {
return { type: 'iframe', element: innerEl, frame: iframe };
}
}
} catch (e) {}
}
return null;
}
function waitForVideo(callback, maxAttempts) {
let attempts = 0;
const platform = detectPlatform();
const config = getPlatformConfig(platform);
const interval = setInterval(() => {
const videoInfo = locateVideoElement(config.videoSelectors);
if (videoInfo || attempts >= maxAttempts) {
clearInterval(interval);
callback(videoInfo);
}
attempts++;
}, CONFIG.initialDelay);
}
function setSpeed(videoInfo, speed) {
if (!videoInfo) return;
if (videoInfo.type === 'html5' || videoInfo.type === 'iframe') {
const video = videoInfo.element;
if (video && video.playbackRate !== speed) {
video.playbackRate = speed;
}
}
}
function playVideo(videoInfo) {
if (!videoInfo) return;
if (videoInfo.type === 'html5' || videoInfo.type === 'iframe') {
const video = videoInfo.element;
if (video && video.paused) {
video.play().catch(() => {
retryCount++;
if (retryCount < CONFIG.maxRetryAttempts) {
setTimeout(() => playVideo(videoInfo), 2000);
}
});
}
}
}
function pauseVideo(videoInfo) {
if (!videoInfo) return;
if (videoInfo.type === 'html5' || videoInfo.type === 'iframe') {
const video = videoInfo.element;
if (video && !video.paused) {
video.pause();
}
}
}
function getCurrentTime(videoInfo) {
if (!videoInfo) return 0;
if (videoInfo.type === 'html5' || videoInfo.type === 'iframe') {
return videoInfo.element ? videoInfo.element.currentTime : 0;
}
return 0;
}
function detectStall(videoInfo) {
if (!videoInfo) return;
const currentTime = getCurrentTime(videoInfo);
if (videoInfo.type === 'html5' || videoInfo.type === 'iframe') {
const video = videoInfo.element;
if (video && !video.paused && currentTime === previousTime && video.readyState > 0) {
stallCounter++;
if (stallCounter > 2) {
pauseVideo(videoInfo);
setTimeout(() => {
playVideo(videoInfo);
stallCounter = 0;
}, 1000);
}
} else {
stallCounter = 0;
}
}
previousTime = currentTime;
}
function generateRandomInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function simulateActivity() {
const activities = [
{ type: 'mousemove', options: { bubbles: true, cancelable: true, clientX: Math.random() * window.innerWidth, clientY: Math.random() * window.innerHeight } },
{ type: 'click', options: { bubbles: true, cancelable: true } },
{ type: 'keydown', options: { bubbles: true, cancelable: true } },
{ type: 'scroll', options: { bubbles: true, cancelable: true } }
];
const activity = activities[Math.floor(Math.random() * activities.length)];
if (activity.type === 'scroll') {
window.scrollBy({
top: Math.random() * 100,
left: 0,
behavior: 'smooth'
});
} else {
document.dispatchEvent(new MouseEvent(activity.type, activity.options));
}
}
function startRandomActivity(interval) {
if (activityTimer) clearInterval(activityTimer);
activityTimer = setInterval(() => {
simulateActivity();
}, interval);
}
function findNextButton(selectors) {
for (const sel of selectors) {
const btn = document.querySelector(sel);
if (btn && btn.offsetParent !== null && !btn.disabled) {
return btn;
}
}
const allButtons = document.querySelectorAll('button');
for (const btn of allButtons) {
const text = btn.textContent.toLowerCase();
if ((text.includes('下一') || text.includes('next') || text.includes('继续')) &&
btn.offsetParent !== null && !btn.disabled) {
return btn;
}
}
return null;
}
function triggerProgressSave() {
const saveButtons = document.querySelectorAll('[class*="save"], [class*="submit"], button.save');
saveButtons.forEach(btn => {
if (btn.offsetParent !== null) {
btn.click();
}
});
}
function setupAutoSave(interval) {
if (saveTimer) clearInterval(saveTimer);
saveTimer = setInterval(() => {
triggerProgressSave();
}, interval);
}
function handleVideoEnded(videoInfo) {
const platform = detectPlatform();
const config = getPlatformConfig(platform);
setTimeout(() => {
const nextBtn = findNextButton(config.nextSelectors);
if (nextBtn) {
nextBtn.click();
}
}, CONFIG.nextClickDelay);
}
function start(videoInfo) {
if (!videoInfo) return;
const platform = detectPlatform();
const config = getPlatformConfig(platform);
setSpeed(videoInfo, CONFIG.speed);
playVideo(videoInfo);
checkTimer = setInterval(() => {
setSpeed(videoInfo, CONFIG.speed);
detectStall(videoInfo);
}, config.checkInterval);
startRandomActivity(config.activityInterval);
setupAutoSave(CONFIG.saveInterval);
if (videoInfo.type === 'html5' || videoInfo.type === 'iframe') {
videoInfo.element.addEventListener('ended', () => handleVideoEnded(videoInfo));
}
const observer = new MutationObserver(() => {
setSpeed(videoInfo, CONFIG.speed);
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
function initialize() {
const platform = detectPlatform();
if (platform === 'unknown') {
console.log('未识别平台,使用默认配置');
} else {
console.log('检测到平台:', platform);
}
waitForVideo(videoInfo => {
if (videoInfo) {
console.log('视频元素已找到,开始自动化');
start(videoInfo);
} else {
console.log('未找到视频元素');
}
}, 20);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialize);
} else {
initialize();
}
window.addEventListener('beforeunload', () => {
if (saveTimer) clearInterval(saveTimer);
if (activityTimer) clearInterval(activityTimer);
if (checkTimer) clearInterval(checkTimer);
});
})();