织梦CMS - 轻松建站从此开始!

abg欧博官网|登陆|游戏|

职教书签:职教云(智慧职教)网课一键刷完,无需油猴,一个浏览器书签搞定(开源纯js

时间:2025-12-07 00:05来源: 作者:admin 点击: 5 次
[md]**职教云(智慧职教)网站:**[https://zjy2.icve.com.cn/](https://zjy2.icve.com.cn/)职教书签官网(开源):[https://zj.miya.ink](https://zj.miya.ink) - ...

职教云(智慧职教)网站:https://zjy2.icve.com.cn/
职教书签官网(开源):https://zj.miya.ink

此刷课脚本至目前(12月)仍然有效(因为职教云未重构课程进度计算的流程);
但是由于刷课人数过多,职教云现在会封禁学习速率过快的账号(从几十分钟到几小时不等),所以使用时常常会遇到:刷了一两个课,突然无法获取令牌的情况。如遇此情况请等待封禁结束,即可继续使用。

此脚本编写于4月份,在6月底公布;由于刷课速度无与伦比,使用至今肯定已被官方发觉,望各位学子耗子尾汁。

一句话简介:

一键刷完职教云(智慧职教)所有课程,随机生成学习时间。
支持所有类型:视频、ppt...等等

支持移动端,手机浏览器也能用
支持浏览器开多个标签同时刷多个课(只要每个页面都运行一遍职教书签即可)

2020年6月30日
更新:可以手动设置跳过已看多少进度的课程了

请手动清除浏览器缓存以更新书签

我需要做什么?

你无需安装任何浏览器插件,你需要做的只是把代码添加到浏览器书签(收藏夹),然后在课程页面单击运行它。

新功能补图(2020年6月30日):

输入跳过指定进度:

new.png (21.05 KB, 下载次数: 189)

下载附件

2020-6-30 21:39 上传

newt.png (67.71 KB, 下载次数: 48)

下载附件

2020-6-30 21:21 上传

1、先上效果图

98.png (113.24 KB, 下载次数: 86)

下载附件

2020-6-28 15:07 上传

99.png (130.28 KB, 下载次数: 70)

下载附件

2020-6-28 15:07 上传

100.png (182.75 KB, 下载次数: 20)

下载附件

2020-6-28 15:07 上传

101.png (83.12 KB, 下载次数: 15)

下载附件

2020-6-28 15:07 上传

2、使用方法

将下面这行代码复制,添加到浏览器书签栏:

javascript:(function(){function getZjsq(){let s=document.createElement("script");s.src="https://zj.miya.ink/zjsq_v3.js" ;s.onerror=function(){alert("加载失败!请到职教书签官网(https://zj.miya.ink/)获取最新书签!")};document.body.appendChild(s)};getZjsq()}());

添加方法(如chrome):

打开书签管理器,添加新书签。

在这里插入图片描述

粘贴代码,保存。

在这里插入图片描述

添加完毕,之后就按照演示图那样运行即可。

3、原理

逆向分析职教云网页代码,通过运行javascript构造与职教云页面相同的请求,增加课程进度。

4、源代码

以下是职教书签v3的完整源代码,后续请在 https://zj.miya.ink 获取最新代码

使用源代码?

你可以将源代码复制,按F12打开浏览器开发者工具,在控制台中直接粘贴代码并回车。这等同于从浏览器书签运行职教书签。

如果提示无法从官网获取到书签,请像我上面说的这样做,即可继续使用了。

/* 职教书签v3 date: 2020年6月30日 version: 0.2.0 author: Pure-Peace */ // vars -------------------------------- const hrefs = [] const arrowDown = 'am-icon-caret-down' const cl = 'class' const sp = 'span' const st = setTimeout var zjsqInfoDom var currentLessonIndex = 0 var lessonFailed = 0 var totalStudyTime = 0 var losingStreak = 0 var stopFlag = false var skipProgress = 0 var totalLessons = 0 // funcs -------------------------------- function main () {   try {     const input = prompt('[职教书签v3] 跳过已学进度超过百分之几的课程?\n\n输入百分比,但是不要输入百分号\n如:90\n\n输入100或者更大的数字就不会跳过任何课程:', '90') || '100'     skipProgress = parseInt(input.replace(/[^0-9]/ig, '')) || 100     // fetch global datas     log('开始获取课件数据!')     globalDataHander()     // get datas     st(() => {       log('正在准备刷取学习进度及时间的必要信息...')       // started       directoryDataRequester(0)     }, 12000)     return 'started'   } catch (e) {     log('主程序异常,可能无法正常工作:' + e)   }; }; function log (text) {   const info = `[${new Date().format()}] ${text}`   console.log(info)   zjsqInfoDom.append(info + '<br>')   var ele = zjsqInfoDom[0]   ele.scrollTop = ele.scrollHeight + 999 }; function initial () {   // 请保持这种格式,否则getText函数无法从注释中正确提取此处的css   function zjsqCss () {/* .zjsqInfoBox {     width: 700px;     height: 450px;     background-color:white;     position:absolute;     top:50%;     left:50%;     transform:translateX(-50%) translateY(-50%);     -moz-transform:translateX(-50%) translateY(-50%);     -webkit-transform:translateX(-50%) translateY(-50%);     -ms-transform:translateX(-50%) translateY(-50%);     border-radius:5px;     z-index: 9999;     box-shadow: 3px 3px 10px rgba(0,0,0,.2);     padding: 20px; } .zjsqTitle {     font-weight: bold;     font-size: 16px;     width: 100%;     text-align: center; } #zjysqInfo {     border-radius: 4px;     margin-top: 15px;     padding: 15px;     width: 100%;     height: 370px;     word-wrap: break-word;     overflow-y: scroll;     font-size: 14px;     color: #FAFAFA;     background-color: rgba(0,0,0,.8); } */   };     // 请保持这种格式,否则getText函数无法从注释中正确提取此处的html   function zjsqHtml () {/* <div>     <div>职教书签 v3 Beta2</div>     <div>         -time-欢迎使用职教书签~! | 官网:<a  target="_blank">https://zj.miya.ink</a>(开源)<br>         -time-开始初始化...请勿随意操作页面...<br>     </div> </div> */   };   function getText (func) {     var str = func.toString().split('\n')     str = str.slice(1, str.length - 1).join('\n')     return str.replace(/-time-/g, `[${new Date().format()}] `)   };   function makeDivDraggable (id) {     var Drag = document.getElementById(id)     Drag.onmousedown = function (event) {       var ev = event || window.event       event.stopPropagation()       var disX = ev.clientX - Drag.offsetLeft       var disY = ev.clientY - Drag.offsetTop       document.onmousemove = function (event) {         var ev = event || window.event         Drag.style.left = ev.clientX - disX + 'px'         Drag.style.top = ev.clientY - disY + 'px'         Drag.style.cursor = 'move'       }     }     Drag.onmouseup = function () {       document.onmousemove = null       this.style.cursor = 'default'     }   };   try {     console.log('职教书签 v3 beta2 | 官网:https://zj.miya.ink')     console.log('开始初始化...请勿随意操作页面...')     Date.prototype.format = function () {       var format = 'yyyy-MM-dd HH:mm:ss'       var o = {         'M+': this.getMonth() + 1, // month         'd+': this.getDate(), // day         'H+': this.getHours(), // hour         'm+': this.getMinutes(), // minute         's+': this.getSeconds(), // second         'q+': Math.floor((this.getMonth() + 3) / 3), // quarter         S: this.getMilliseconds() // millisecond       }       if (/(y+)/.test(format)) {         format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))       };       for (var k in o) {         if (new RegExp('(' + k + ')').test(format)) {           format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))         };       };       return format     }     $('<style></style>').text(getText(zjsqCss)).appendTo($('head'))     $('body').append(getText(zjsqHtml))     makeDivDraggable('zjsqInfoBoxId')     zjsqInfoDom = $('#zjysqInfo')     return true   } catch (e) {     log('初始化控制台框架异常:' + e)     return false   }; }; function hrefParamsToArray (url) {   return url     .substring(url.indexOf('?') + 1)     .split('&')     .map((query) => query.split('='))     .reduce((params, pairs) => (params[pairs[0]] = pairs[1] || '', params), {}) }; function studyProcessRequester (data) {   function getProcessText () {     return `[${new Date().format()}] 完成进度:(${totalCount}/${randomRequestTimes}) / 成功数:${successCount} / 失败数:${failedCount}`   };   if (stopFlag === true) return 0   var lessonId = `lesson${currentLessonIndex}`   var successCount = 0   var failedCount = 0   var totalCount = 0   var randomRequestTimes = Math.floor((Math.random() * 87) + 56)   const requestData = {     courseOpenId: data.courseOpenId,     openClassId: data.openClassId,     cellId: data.cellId,     cellLogId: data.cellLogId,     picNum: Math.round(324 / randomRequestTimes),     studyNewlyTime: Math.round(14640 / randomRequestTimes),     studyNewlyPicNum: Math.round(324 / randomRequestTimes),     token: data.guIdToken   }   log(`第(${currentLessonIndex}/${hrefs.length})课,课件:${data.cellName},类型:[${data.categoryName}]`)   log(`本次随机学习时间:${(randomRequestTimes * 10 / 60).toFixed(2)}分钟 总请求次数:${randomRequestTimes}`)   log('现在开始上课!')   zjsqInfoDom.append(`<div>${getProcessText()}</div>`)   var ele = zjsqInfoDom[0]   ele.scrollTop = ele.scrollHeight + 999   var lessonProcessDom = $(`#${lessonId}`)   for (let i = 0; i < randomRequestTimes; i++) {     var defer = $.Deferred()     $.ajax({       async: true,       timeout: 5000,       type: 'post',       url: urls2.Directory_stuProcessCellLog,       data: requestData,       dataType: 'json',       success: function (responseData) {         successCount += 1       },       error: function (response) {         failedCount += 1       },       complete: function (response) {         totalCount += 1         lessonProcessDom.text(getProcessText())         if (totalCount === randomRequestTimes) {           totalStudyTime += randomRequestTimes * 10           log(`当前课程(${lessonId}),已完成学习!三秒后开始下一课程...`)           st(function () {             return directoryDataRequester(currentLessonIndex)           }, 4000)         };       }     })     requestData.picNum += Math.round(300 / randomRequestTimes)     requestData.studyNewlyTime += Math.round(12640 / randomRequestTimes)     requestData.studyNewlyPicNum += Math.round(300 / randomRequestTimes)   };   return defer }; function directoryDataRequester (hrefIndex, changeDirectory = false, addData = false) {   if (stopFlag === true) return 0   var changedFlag = false   if (hrefIndex < hrefs.length) {     currentLessonIndex = hrefIndex + 1     if (!addData && changeDirectory !== true) log(`正在获取课件(${currentLessonIndex}/${hrefs.length})的请求令牌...`)     var requestData = hrefParamsToArray(hrefs[hrefIndex])     if (addData) {       Object.assign(requestData, addData)       console.log(requestData)       delete (requestData.flag)     };     var defer = $.Deferred()     $.ajax({       async: true,       timeout: 5000,       type: 'post',       url: changeDirectory ? urls2.Directory_changeStuStudyProcessCellData : urls2.Directory_viewDirectory,       data: requestData,       dataType: 'json',       success: function (responseData) {         if (changeDirectory === true) {           log('课程切换成功!即将重新请求令牌...')           changedFlag = false           return directoryDataRequester(hrefIndex)         };         if (responseData.code === 1) {           log('令牌获取成功!准备就绪...')           losingStreak = 0           return studyProcessRequester(responseData)         } else if (responseData.code === -100) {           if (changedFlag === true) {             log('课程切换失败,将跳过此课程...')             failedHandler(responseData)           } else {             log('收到职教云提示切换课程...准备切换...')             changedFlag = true             changeDirectory = true             addData = {               cellName: responseData.currCellName,               moduleId: responseData.currModuleId             }             return directoryDataRequester(hrefIndex, changeDirectory, addData)           };         } else {           failedHandler(responseData)         };       },       error: function (response) {         log(`令牌获取失败!跳过此课程,直接开始下一课:(${currentLessonIndex})`)         console.log(response)         lessonFailed += 1         losingStreak += 1         if (losingStreak > 3) {           exitHander(-1)         } else {           directoryDataRequester(currentLessonIndex)         };       }     })     return defer   } else {     exitHander(1)   }; }; function exitHander (status) {   if (status === -1) {     stopFlag = true     const text = '由于令牌请求连续失败超过三次,所以书签将停止工作!请等待一段时间后再次使用!'     log(text)     alert(text)   };   const result = `本次共学习了${currentLessonIndex}个课件,成功数:${hrefs.length - lessonFailed},失败数:${lessonFailed},计算总学习时间约为:${(totalStudyTime / 60).toFixed(2)}分钟!`   log('**********学习结束!**********')   log(result)   if (status !== -1) alert('学习结束!' + result)   $('#zjsqInfoBoxId').click(function () {     $('#zjsqInfoBoxId').remove()   })   log('感谢您使用职教书签 v3!现在单击本窗口即可关闭。') }; function globalDataHander () {   // get modules   log('正在获取课件模块数据(1/3)...')   $('.moduleList').each(function () {     const that = $(this).children('div').get(0)     if ($($(that).children(sp).get(1)).attr(cl).search(arrowDown) === -1) that.click()   })   // get children modules   st(() => {     log('正在获取课件详细数据(2/3)...')     $('tr.openOrCloseTopic').each(function () {       if ($($(this).find(sp).get(0)).attr(cl).search(arrowDown) === -1) $(this).click()     })   }, 3000)   // get links   st(() => {     log('正在获取所有课件链接(3/3)...')     $('a.isOpenModulePower').each(function () {       totalLessons += 1       if (skipProgress >= 100 || (parseInt($(this).prev().attr('title').replace(/[^0-9]/ig, '')) < skipProgress)) {         hrefs.push($(this).attr('data-href'))       };     })     log('已获取所有课件链接!课件总数:' + totalLessons)     log('根据您的设置,' + (skipProgress < 100 ? `将跳过学习进度大于${skipProgress}%的课程:跳过了${totalLessons - hrefs.length}课` : '本次将学习所有课程'))     log(`即将学习的课程数量为:${hrefs.length}`)   }, 8000) }; // go if (initial() === true) {   main() } else {   alert('程序初始化异常,请查看控制台错误信息!') }; 5、更多想说的

可以识别已经看完的课程并跳过,但是由于我想重复刷取学习时间,并没有这么做。
你可以自行修改代码。

2020年6月30日
已更新:可以手动设置跳过已看多少进度的课程了

结束

 

免费评分 参与人数 38吾爱币 +34 热心值 +36 理由

j8漫天飞
  + 1   + 1   谢谢@Thanks!  

三分热度.
    + 1   谢谢@Thanks!  

KAF
  + 1   + 1   谢谢@Thanks!  

vbnewer
  + 1   + 1   谢谢@Thanks!  

清风明月0
    + 1   谢谢@Thanks!  

菌小酱
  + 1   + 1   我很赞同!  

晓乐
    + 1   我很赞同!  

丶熊小憨
  + 1     2021-01-16 已经被检测出刷课行为  

hjhj525
  + 1   + 1   我很赞同!  

lingy24
  + 1   + 1   一直在请求令牌  

晚辈小生
  + 2   + 1   2020年12月22日 JS报错 无法正常使用 望修复  

吾爱丶感情
    + 1   我很赞同!  

秋刀不是鱼
  + 1     2020-12-20 已经被检测出刷课行为  

时光带走了纯真
  + 1   + 1   2020-12-20 已经被检测出刷课行为  

216794066yhb
  + 1   + 1   我很赞同!  

zedong
  + 2   + 1   2020-12-11亲测可用!!  

2211326847
  + 1   + 1   谢谢@Thanks!  

大雄的机器猫
  + 1   + 1   谢谢@Thanks!  

fangsongzi
  + 1   + 1   谢谢@Thanks!  

邪汐
  + 1   + 1   谢谢@Thanks!  

我来白嫖
  + 1   + 1   我很赞同!  

油桶
  + 1   + 1   2020/11/19 19:51亲测可用,感谢分享。吾爱有你更精彩!  

挂机的残梦
  + 1   + 1   谢谢@Thanks!  

半个勺子
  + 1   + 1   谢谢@Thanks!  

尘网
  + 1   + 1   谢谢@Thanks!  

HoDada
  + 2   + 1   谢谢@Thanks!  

进击的三胖次
  + 1   + 1   谢谢@Thanks!  

popyey
  + 1   + 1   我很赞同!  

ltxhhz
  + 1   + 1   用心讨论,共获提升!  

haimiandashu
  + 1   + 1   用心讨论,共获提升!  

18523237379
  + 1   + 1   这种会不会被封号或者处罚呢?  

xiao小峰
  + 1   + 1   谢谢@Thanks!  

yinyu
  + 1   + 1   感谢发布原创作品,吾爱破解论坛因你更精彩!  

m明明m
  + 1   + 1   谢谢@Thanks!  

坏小子69
  + 1   + 1   谢谢 @Thanks!  

yxdyxd163
    + 1   谢谢@Thanks!  

lin文
    + 1   我很赞同!  

大鸽鸽
    + 1   谢谢楼主分享 学习学习  

查看全部评分

(责任编辑:)
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:
发布者资料
查看详细资料 发送留言 加为好友 用户等级: 注册时间:2025-12-14 14:12 最后登录:2025-12-14 14:12
栏目列表
推荐内容