ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

学习通刷课脚本因何失效?浏览器自动化与反作弊机制深度拆解

学习通刷课脚本因何失效?浏览器自动化与反作弊机制深度拆解 看到这个标题进来的朋友应该都对“学习通”这三个字有故事。最近一段时间大大小小的技术群里飘着同一句话“学习通浏览器刷课脚本已失效”。我在不少地方看到有人翻出篡改猴、脚本猫里的小脚本自嘲——昨天还能跑今天开屏就报错课程进度纹丝不动。谷歌浏览器右下角弹通知、Edge 的扩展列表里一片灰整个链路一夜之间全断了。先说明一个态度这篇文章不教怎么继续刷课也不提供任何绕过平台检测的代码后续内容里所有关于脚本的讨论都停留在“原理复盘”层面。我花精力写这件事是想借“一个失效脚本”这么好的现成教材把浏览器脚本的工作原理、用户脚本管理器油猴、篡改猴、脚本猫这类工具的机制、平台反作弊的工程思路、以及这些知识能迁移到哪些正当方向上一次讲透。对刷课本身我持明确反对态度——省下来的时间本来可以用在学习上但“为什么它会失效”这个过程里的技术含量确实值得整理出来。1. “已失效”三个字恰恰是分析价值最高的地方1.1 脚本“批量阵亡”不是偶然是必然节奏只要你在网上搜过“学习通 脚本”“浏览器刷课”大概率见过两类帖子一类是几个月前发的“亲测可用”另一类是这几天刚发的“已失效”“求更新”。这两类帖子交替出现本身就是这类工具的生命周期规律。为什么脚本会集体失效因为这类脚本的运行前提是把网页当成一个“已知结构”的对象按钮在哪个节点、播放器是什么组件、学习进度存在哪个全局变量里、后端接口的参数怎么拼。页面结构一旦大改脚本第一步就挂了。平台方又不傻每次迭代版本不只是为了加功能很多时候就是在堵这些口子。学习通这类产品本身是前端工程化做得比较重的系统页面组件库、路由结构、接口签名策略说换就换一个版本更新就能让市面上八成脚本原地报废。我在本地环境里跑过一次这些失效脚本看到一个很有意思的现象脚本报错信息几乎清一色停在“找不到节点”“undefined is not a function”。有的脚本在打点上报时还用了旧版接口字段结果接口返回的响应体结构变了脚本直接把 error 当成功处理表现就是“任务显示完成后台零进度”。这些现象放在一起你就能看出一条客观规律凡是没有官方支撑、纯靠逆向页面结构的自动化方案本质上都在做“易碎品”平台只要愿意投入最低限度的治理成本就能把这些脚本全部打掉。1.2 失效消息传开暴露的是使用者对工具的理解盲区“已失效”三个字传得这么快还说明另一个问题很多人从头到尾只是“会用脚本”并不清楚脚本怎么工作更不知道它为什么会失效。大家打开脚本猫或篡改猴看到“学习通助手”“网课加速”之类的东西点了安装就往浏览器里塞然后在课程页面看着进度自己动以为万事大吉。这种使用方式背后的风险其实是叠满的。第一脚本本身是第三方代码你在页面上执行的所有操作、你登录态里的 Cookie、甚至你的账号标识对脚本作者来说几乎是透明的。市面上这些脚本鱼龙混杂有些好心的作者确实免费维护但也有夹带私货的案例——你以为在刷课实际上脚本在偷偷向后端上报你的账号数据或者塞广告甚至有更恶意的行为。第二浏览器扩展和脚本插件拥有你在特定页面下的全部操作权限一个“失效”的脚本如果保留着旧的请求逻辑一旦开发者做坏事账号安全完全没有保障。我见过不止一个例子账号被异地登录后刷出了大量奇怪消费记录排查下来才发现是装过某个来路不明的免费脚本。所以在往下读之前我希望你把“失效”当成一次提醒任何能够替你执行浏览器操作的代码都值得你用审视的眼光看待。技术本身是中性的但你不了解自己在运行什么就是风险本身。1.3 抱着考古的心态去研究它收益完全不同我始终觉得分析一个已经失效的脚本比分析一个正在运行的脚本要安全也更有价值。已经失效的方案意味着平台已经把它堵上了它没有了“可用”的属性只剩下“技术样本”的价值。这时候打开控制台逐行看它要做什么、是怎么写的、为什么会失败心态就完全不同了——你不是在寻找漏洞而是在学习一个系统的行为模式和工程实现。这篇文章的核心框架就是基于这个考古视角展开的先还原这类脚本在浏览器里到底做了什么再分析平台侧用什么样的工程手段让它们集体失效最后聊一聊这些技术点迁移到正经方向能怎么用。2. 这类脚本在浏览器里实际做了什么三层事2.1 第一层读懂页面结构定位“课程元素”一个刷课脚本启动后第一件事永远是“找东西”。它要知道当前页面是什么课程、哪个章节、进度条在哪里、播放按钮长什么样。这些信息在网页里全部以 DOM 节点的形式存在所以脚本的第一步通常就是请求一堆元素选择器比如document.querySelector一套组合拳去匹配视频容器、章节列表、下一节按钮。这里有个关键点学习通这类系统走的是动态渲染很多 DOM 节点是 JavaScript 异步创建的。脚本如果直接去查节点很可能拿到null所以早期能用的脚本基本都是“轮询式”的——用一个定时器反复查询页面结构每几百毫秒扫一次直到目标节点出现再执行下一步。这类代码里最常见的工具就是setInterval写得好一点的会加个MutationObserver监听 DOM 变化比盲轮询高效得多。我在复盘失效脚本时看到不少经典写法有的脚本先读取页面里嵌着的initData或window上的全局变量把课程 ID、章节 ID、学习时长之类的数据一次性抓出来再决定要从哪里开始。这是一种很聪明的设计——不管页面按钮怎么变只要后端在渲染时暴露的数据结构没变脚本就还能跑。可反过来一旦平台把这些全局变量移除或改名脚本就会瞬间变盲。2.2 第二层模拟用户操作触发页面事件找到了播放器、找到了章节下一步就是“操作”。刷课脚本常见手段是让视频自动播放、静音、倍速然后定时“翻页”进入下一节。这里面的技术核心是浏览器事件机制脚本调用play()、click()本质上是在触发一个 JavaScript 事件让播放器进入播放状态。但这里藏着一个很深的坑浏览器里的“用户真实点击”和“脚本触发的程序化事件”底层是有区别的。现代浏览器会为真实用户操作生成isTrusted: true的事件而被脚本dispatchEvent伪造出来的事件isTrusted是false。平台侧的 JavaScript 代码完全可以通过检查event.isTrusted来判断这个动作是不是真人点的。早期刷课脚本能在页面上为所欲为很多时候是平台压根没做这种校验后来大量脚本失效就有一部分原因正是平台开始在关键事件上加isTrusted检查。还有更“物理层”的检测。真人用鼠标点按钮鼠标轨迹是有加速度、有抖动的而脚本执行点击是一瞬间直接命中目标区域。平台如果在前端采集了 mousemove 事件再把轨迹数据传到后端做行为特征分析脚本行为的平滑度特征和真人差异会非常明显。这种差异不靠代码能轻易绕过去除非你连鼠标轨迹都一起伪造那复杂度就完全不同了。2.3 第三层直接调用接口上报学习进度操作播放器只是表面动作真正决定“学分到账”的是页面不停向后端发送的学习进度上报请求。你在学习通上打开一个视频播放器每隔一段时间就会把“当前看到第几秒”同步给服务器服务器这边记下了足够时长才判定你完成学习。所以刷课脚本最核心的一步往往是直接模拟这些“心跳请求”。脚本不需要真的把视频播完它只需要按节奏向后端接口发送“我看到第 300 秒了”这种消息并且让消息的时间序列看起来合理服务器就可能相信它。这类请求通过浏览器开发者工具里的 Network 面板就能抓到参数、请求头、Cookie 一应俱全。但“抓包能抓到”和“发出去能被接受”是完全两回事。后端的校验策略才是真正的生死线。我见过很多脚本死在这一步平台给请求参数加了一个临时签名这个签名是由前端 JavaScript 在本地算出来再拼在请求里的而脚本如果只是机械地重放旧数据签名值过期服务器直接返回 403 或一条“参数错误”。这就是为什么需要把“浏览器里发生了什么”和“服务器怎么校验”放在一起看只懂怎么点按钮永远理解不了失效的本质。3. 平台反作弊升级从失效现象逆向看到的工程链路3.1 前端埋点越来越密脚本的行为“看得见”平台想要和脚本对抗第一步不是拦截而是“看见”。我在研究前端监控工程时发现现在稍有点规模的教育类产品前端埋点都已经做了很多层页面停留时长、点击事件、播放器状态切换、鼠标移动轨迹、甚至 tab 是否处于后台焦点都会被采集和上报。拿“页面焦点”来说真人看视频时页面大概率是激活状态偶尔切走看个资料焦点回正而刷课脚本通常在后台标签页运行或者用户把浏览器最小化。播放器自己的visibilitychange事件、blur/focus事件全都会把这些状态暴露出去。有些平台甚至会让播放器在上报数据里带上“页面可见性”字段一旦检测到长时间后台播放就会判定为异常这比判断某个按钮是不是被点过要高级得多。更关键的是这些埋点数据不止在浏览器里被检查还会被汇总到后端做关联分析。比如“一个账号在凌晨两点以 6 倍速看完某门课”“一个 IP 下面一口气挂了几十个账号”这些特征单个看都很普通但放在一起就是一个异常行为画像。所以你看平台上部分账号被标记、被拉黑不一定是某一个具体请求出了问题更可能是行为模型判断“这个账号的整个使用过程不像真人”。3.2 接口签名不再裸奔每次请求都带“防伪标记”平台反作弊里最能体现工程水平的一层是接口签名。为什么很多脚本死于“一觉醒来全部失效”很可能不是因为页面变了而是因为后端对请求参数加了一道新签名规则前端在发起请求前会把时间戳、随机数、课程 ID 等参数按一定规则拼接再用一串算法算出一个签名值附在请求参数里。服务器收到请求后会按同样的规则重新计算一遍两边不一致就直接拒绝。这种机制之所以能干掉大量脚本是因为脚本作者需要逆向出“前端算法是什么”。可前端算法是可以随时换的平台只要更新一版前端代码改一下拼接规则或加密函数的位置旧脚本就算照着原逻辑发送请求签名也对不上。这种“动态密钥轮换”加上“不同的接口用不同签名规则”的组合拳成本极低却能把大多数机械重放请求的脚本挡在门外。你如果抓包看这种请求会发现参数列表里除了业务字段还有一些长得像哈希值的字符串那就是签名。普通用户完全无感但脚本作者会非常头痛——他需要找准签名函数、复制实现逻辑还要保证后续平台不发版只要平台发版脚本就要跟着改。这场博弈的节奏完全不在脚本作者手里。这个原理和你在网上看到的“为什么有些接口抓不到包”“为什么请求重放到另一台机器就失败”其实是同源的。3.3 服务端进度校验从“你说了算”到“我不信你”最狠的一刀永远在服务端。早期刷课脚本能猖獗一段时间是因为后端逻辑比较天真前端说“我看完了十分钟”后端就把十分钟加到进度里。平台会发现这种信任何等幼稚——一个前端的“自我报告”根本不值得信任。平台升级后服务端会把进度状态切成一个“严密的状态机”视频必须经过“启动播放”状态、“持续心跳”状态、“缓冲暂停”状态多个状态点之间的时间序列要合理最终才能进入“完成”状态。单纯往前端接口里发一个“完成”信号后端根本不吃这套它要看到完整的事务性动作链条。检查包括但不限于播放器实例是否初始化成功播放中是否发生了至少一次用户交互心跳上报的时间间隔是否规律总观看时长和视频时间轴是否匹配。还有一个常见手段是随机插入“防刷元素”。比如播放中间突然弹一道小测验或者在视频特定进度点要求点击一次“确认继续学习”再比如把进度划分成多个时间片每个时间片都要收到独立上报缺少任意一片都算“未完成”。这些机制在技术上都算不上很高深但组合在一起就让脚本作者的模拟成本直线上升。你还在想办法伪造最后那个“完成”请求结果平台早就不关心那个请求了——它看你前面几百个心跳有没有漏发。4. 失效是一场洗牌也是对自动化能力边界的再认识4.1 把研究脚本的劲头用在浏览器自动化测试上聊了这么多“刷课脚本为什么死”真正值得转过来的点是研究这些脚本时练出来的能力正好和前端自动化测试高度重合。一个简单的刷课脚本要处理“等待节点出现”“判断播放状态”“模拟点击”这些逻辑当你把这些技术放到合规的自动化测试场景中价值就完全不同了。举个例子用 Playwright 写一个用例去做网站回归测试打开页面、等待某个异步组件渲染、点击按钮、断言网络请求是否发出。这套流程里用到的“等待策略”“选择器定位”“事件触发”和刷课脚本里的思路如出一辙只是目标从“跳过学习”变成了“保障产品质量”。我身边不少做前端的朋友入门自动化测试时都会经历一个阶段先写几个油猴脚本解决自己日常重复操作的问题再去写测试用例发现很多东西是通的。推荐两条值得上手的路线一是学一下 Playwright 或 Puppeteer把真实浏览器操作流程跑通二是系统地看一遍 JavaScript 事件循环和 DOM 规范把isTrusted、MutationObserver、requestAnimationFrame这些概念搞明白。这些知识在刷课脚本里是碎片化的但在正经自动化项目里就是地基。4.2 能做正事的浏览器脚本方向其实多得是浏览器脚本这个技能树点在刷课上是最亏的。把同样的技术能力迁移一下合规和实用兼备的方向非常多。举几个我实际做过或见别人做得很漂亮的方向表单自动填写某些内部系统每次都要重复填一堆表单完全可以写个油猴脚本把常用值一键带出。这活儿没有任何违规风险还能省下大量时间。网页数据整理临时需要把网页上的表格数据导出成 CSV或者把多页数据汇成一份清单脚本在浏览器侧抓取循环请求很容易实现。前端开发辅助给测试环境页面加一个“一键填充假数据”按钮给联调页面展示隐藏的接口信息这类“开发自己用的工具”在团队里很受欢迎。RPA 办公自动化在允许自动化办公的软件体系内把重复录入、跨系统搬运数据的流程做成半自动脚本效率和成就感都比刷课强得多。关键在于想清楚边界只要自动化的目标是“提升自己的工作效率”而不是“绕过第三方平台的规则去获取不正当收益”这件事的方向就是对的。技术能力是一回事判断能力是另一回事。4.3 我自己的几点实在建议按我在浏览器自动化上折腾多年的经验结合这次“学习通脚本集体失效”的观察给你几个实在的建议。第一所有“免费”“一键”“全自动”的第三方脚本安装前先打开源码看一遍。只看了十行也能看出作者是想做工具还是想搞数据。看不懂代码的至少认准那些建了 GitHub 仓库、有明确更新日志、使用者反馈透明的脚本远离来源不明的打包分享。第二如果你对这类脚本的原理感兴趣不要只停留在“能不能用”这个层面打开开发者工具去拆解它为什么能跑、为什么挂了。浏览器里按 F12看 Network、看 Console、看 Sources这个过程积累的调试能力是任何培训班都给不了你的。我对浏览器工作原理的很多理解恰恰是大学时代折腾各种“不正经”脚本时打下的底子但后来我把时间和能力都转到了测试工程和开发工具上。第三这类“已失效”的脚本最好的去处是本地保留一份用于学习分析而不是再去网上求“新版本”。平台一旦开始认真做反作弊新版本的出现只会把大量用户的账号置于风险之中。与其为了省几个小时的学习时间冒账号异常的风险不如正视平台规则用正常方式完成学习。把那一两个小时花在研究怎么用脚本上多半已经够你把那门课认真学完了。最后再说一句实在话研究失效脚本核心收获不是让你找到一条新路子绕过平台而是让你真正弄懂网页应用的运行原理、自动化技术的边界和平台风控的工程思路。这些知识体系放到任何正经方向都能产生正向回报。现在浏览器技术栈迭代这么快更值得我们把时间和热情投在建设性的事情上。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进