ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

B站创作激励自动领取:纯控制台JS脚本设计与实战

B站创作激励自动领取:纯控制台JS脚本设计与实战 1. 为什么要做这个脚本从一次漏领激励说起1.1 创作者激励这个事很多人都会漏领做B站的朋友应该都清楚创作激励计划并不是每天自动到账的而是按周期结算、按页面提示手动领取。你辛辛苦苦把视频发上去等播放量、点赞、投币这些数据达标了后台会给你生成一笔激励收益这时候你必须在规定时间内去“创作中心-收益”或者对应的激励页面点一下“领取”按钮钱才会真正落到你的账户里。问题就出在这个“手动领取”上。我身边有不少UP主包括我自己都有过错过领取周期的经历。有时候是视频数据正好卡在凌晨更新有时候是页面入口藏在二级菜单里根本找不到更多时候就是单纯忘了。等想起来再去看本期奖励已经过期那种感觉真的跟丢钱一样难受。所以我一直在想能不能写一段脚本让浏览器自己帮我把“领取”按钮点了。于是就有了这个项目一段纯控制台JS脚本不需要安装任何东西打开浏览器F12粘贴进去回车脚本会自动扫描页面上所有可领取的按钮逐个点击把该领的奖励全部领完。而且这个脚本不只针对B站某一个页面它按文案特征去匹配按钮所以只要是长得差不多的领奖页面基本都能直接通用。1.2 为什么用纯控制台不用油猴脚本可能有人会问同类需求用油猴脚本不是更常见吗后台挂着脚本一进页面自动运行体验确实更好。那我为什么偏偏要写成“纯控制台”版本这里有几个很现实的考虑。第一油猴脚本有安装门槛。你得先装Tampermonkey扩展再找脚本地址再安装启用这一套流程对不熟悉浏览器扩展的UP主来说并不友好。而且有些浏览器、有些公司电脑、有些学校机房扩展安装权限是被锁死的你连应用商店都进不去。控制台就不一样了任何主流浏览器都有F12开发者工具只要你打开网页就能用零安装零依赖。第二这类“领奖励”操作本身就是低频行为。创作激励不是每天都要领的通常一个周期领一次就够了。为了一周一次甚至一个月一次的点击专门装一个长期驻留的油猴脚本属于杀鸡用牛刀。控制台脚本用完即走不占内存不留在后台心理上也更干净。第三控制台脚本在调试和临时修改上更方便。你可以在控制台里直接改代码、直接跑、直接看报错整个过程是可交互的。油猴脚本出了问题还得去脚本管理页面查日志、重新加载流程长了一截。当然油猴脚本也有它的价值。它适合需要长期、自动、无感知运行的场景。事件驱动式地检测DOM变化、自动重试、后台值守这些都是纯控制台脚本不太好做的事情。所以在文末我会单独讲一下怎么把这段控制台脚本改造成油猴脚本两头通吃。简单总结高频周期任务选油猴低频一次性任务选控制台。我这个脚本解决的就是“偶尔打开后台发现有一排奖励忘了领”的典型场景控制台方案是最合身的选择。1.3 控制台脚本的原理一点都不神秘在写代码之前先把这个东西的原理说透。浏览器控制台为什么能自动点击页面上的按钮其实没有任何黑魔法。你在控制台里输入的每一行JS都是在这个当前页面的上下文里执行的也就是说你等于在B站自己的脚本环境里跑了一段代码。你写的document.querySelector能拿到页面元素你写的btn.click()能触发按钮点击是因为控制台被浏览器赋予了当前页面级别的权限其他网页脚本能做的事你在控制台里也能做。这就解释了为什么纯控制台脚本不需要任何插件。油猴脚本的本质其实也就是借助扩展机制往页面里注入一段JS最后执行的还是浏览器原生API。控制台省掉的是中间这层注入壳子直接把代码交到开发者工具里跑。理解了这一层后面所有代码看起来就都不神秘了。2. 脚本整体设计别写死按钮要“全页面通用”2.1 通用匹配思路按文案识别而不是按ID识别标题里有个关键词特别值得注意——“全游戏领奖页面通用”。如果我是写死某个按钮的ID或者class那这个脚本换个页面就废了谈何通用所以设计脚本的第一步就是放弃“精确寻址”改用“语义识别”。什么意思就是我不关心这个“领取”按钮具体长什么样叫什么ID属于哪个div我只关心它的文字内容是不是“领取”“立即领取”“领取奖励”之类。用IT行业的话说前者是强耦合实现后者是面向行为编程。实际做法很简单遍历页面上所有的button元素以及长得像按钮的a标签、div标签把它们的textContent取出来去掉首尾空格再用正则去匹配“领取”相关的关键词。匹配成功说明这个元素大概率就是一个可点的领奖按钮然后我再判断一下它是不是可点击状态是的话就直接执行click。这套逻辑的好处是显而易见的不管B站后台怎么改版只要按钮文案里还带着“领取”两个字脚本就还能用。事实上我用它在B站的游戏激励页、活动奖励页、任务中心页都跑过表现都很稳定这就是文案匹配的通用性带来的收益。这里引出一个比较常见的点在JS里判断字符串是否包含某个关键词最经典的方式就是用正则或者includes方法。像我这里因为要同时匹配“领取”“立即领取”“领取奖励”多个词所以用正则最方便一个表达式全搞定。热搜词里也有人问“js判断字符串是否包含”这里顺便解释一下includes只适合精确判断单个字符串正则适合批量模糊匹配按需选择就行。2.2 设计取舍为什么不锁死固定类名有人可能疑惑B站页面上那些领取按钮明明是有固定类名的直接选类名不是更精准吗确实更精准但也更脆弱。B站前端上线新版本之后改类名是常有的事今天叫reward-btn明天可能就改成income-btn-2025你看上去只是页面换了个皮肤脚本却直接失联了。更重要的原因是B站后台其实是一个很大的系统“创作者激励”只是其中一个模块不同分区、不同活动的领奖页面很可能由不同团队开发。有的页面用el-button有的页面用原生button有的甚至是一个div被JS绑定了点击事件。这种页面之间共同的唯一公约数是什么只有用户能看到的那个文案。所以文案匹配在这个场景下不是偷懒而是经过取舍之后最稳的方案。当然文案匹配也不是完全没有误触风险。比如页面上可能有一个“领取规则”的弹窗按钮“领取记录”的Tab页这些文案里也含有“领取”两个字但它们不是领奖按钮。为了解决这个问题我在代码里做了两个处理一是正则要求“领取”后面的字不能是“规”“记”“说”之类降低误命中率二是把“立即领取”“领取奖励”这类高置信度词放在优先匹配的前面。对付这种多场景页面宁可少点一个也不要乱点一个所以脚本整体上遵循“宁缺毋滥”的原则。2.3 完整核心代码基础版下面这段就是脚本的核心部分我加了不少注释常规情况下直接能用。(function () { // 最大点击次数防止意外循环导致页面卡死 const MAX_CLICK 20; // 匹配文案优先精确词组其次才用宽松正则 const HIGH_CONFIDENCE [立即领取, 领取奖励, 一键领取]; const NORMAL_RULE /领取(?!规则|记录|说明|详情)/; // 找出页面里所有可点击元素button、带role的标签、a标签 const candidates Array.from( document.querySelectorAll(button, a, [rolebutton], [class*btn]) ); let clickedCount 0; const clickedTexts []; for (const el of candidates) { if (clickedCount MAX_CLICK) break; const text (el.textContent || ).trim(); if (!text) continue; // disabled 状态直接跳过 if (el.disabled || el.getAttribute(aria-disabled) true) continue; // 高置信度词组优先 const isHigh HIGH_CONFIDENCE.some(word text.includes(word)); // 普通正则兜底 const isNormal NORMAL_RULE.test(text) text.length 20; if (isHigh || isNormal) { el.click(); clickedCount; clickedTexts.push(text); console.log([已点击], text); } } if (clickedCount 0) { console.log(没有找到可领取的按钮请确认当前页面是否为领奖页面); } else { console.log(执行完毕共点击 ${clickedCount} 个按钮, clickedTexts.join(、)); } return clickedCount; })();需要说明的是这段代码是“一次性扫描”的执行模型适合页面加载完毕之后手动运行。如果你打开页面时奖励还没完全渲染出来建议先等两三秒再执行或者下面我给的轮询加强版会更合适。2.4 轮询加强版自动等待动态加载的内容很多领奖页面并不是一次性把按钮全部渲染出来的而是异步请求、分段加载。尤其是游戏激励页往往先显示一部分往下滚动才加载下一批。面对这种情况一次性的扫描就不够用了。加强版的做法是做一个带轮询的循环每2秒自动扫描一次发现新的可领取按钮就点击直到连续几轮都扫描不到新按钮才自动停止。这样你贴完代码脚本就自己在后台“干活”完全不用管。(function autoClaim() { const MAX_ROUNDS 30; const INTERVAL_MS 2000; let round 0; let lastClickCount -1; const CLICK_KEYWORDS [立即领取, 领取奖励, 一键领取]; function scanAndClick() { round; const buttons Array.from(document.querySelectorAll(button, a, [rolebutton])); let clicked 0; for (const btn of buttons) { const text (btn.textContent || ).trim(); if (!text) continue; if (btn.disabled) continue; const matched CLICK_KEYWORDS.some(k text.includes(k)); if (matched) { btn.click(); clicked; console.log([轮询自动点击], text); } } console.log(第 ${round} 轮扫描完成本轮点击 ${clicked} 个按钮); // 连续两轮没有新点击或达到轮次上限自动停止 if (clicked 0 lastClickCount 0) { console.log(连续两轮无新按钮自动停止); return; } lastClickCount clicked; if (round MAX_ROUNDS) { console.log(达到轮次上限自动停止); return; } setTimeout(scanAndClick, INTERVAL_MS); } scanAndClick(); })();这里有个细节我用setTimeout而不是setInterval。如果用setInterval上一次扫描还没跑完下一轮就开始了可能造成重复点击。setTimeout只在上一轮完全执行完之后才安排下一轮避免了这种并发冲突这也是一个我在实际调试中踩过的坑。3. 实操过程从打开控制台到一键跑完3.1 第一步找到正确的领奖页面脚本写好了关键是怎么用。第一步不是开控制台而是先找到正确的页面。以B站为例创作者激励计划的领取入口一般藏在“创作中心”的收益相关模块里不同时期的入口位置略有不同但大体路径是点头像进入创作中心在左侧菜单找到“收益”或“服务中心”再找到“激励计划”或“任务中心”相关的子页面。更省事的办法是直接走B站官方的个人中心链接。你登录之后在地址栏输入创作中心的网址回车就能直达。这里我先卖个关子不写具体域名以免以后链接路径变动误导大家但记住一个规律能用个人中心直达的页面优先用个人中心不要从首页一层层点进去层级越深越容易迷路。还有一点如果你在某个页面已经看到了“可领取”的红色角标或者数字提示那恭喜你这个页面基本就是脚本的目标页。你可以先手动确认一下页面上确实存在“领取”按钮再运行脚本这样成功率最高。3.2 第二步打开控制台并粘贴脚本页面准备好了接下来就是打开控制台。Windows用户按F12苹果用户按OptionCommandI都能直接调出开发者工具。如果某些笔记本需要按FnF12那就顺手按一下。打开之后点击面板顶部的“Console”标签切到控制台页。这里有一个很多新手会遇到的坑第一次打开控制台时页面会提示“按回车继续”或者自动定位到一个像输入框的位置。请不要担心这是正常的你直接在里面粘贴代码就行。但要注意有些浏览器为了防止复制粘贴会在粘贴时弹出确认框这时候选“允许粘贴”就好。粘贴完代码之后按回车执行。正常情况下你会立刻在控制台里看到脚本输出的日志比如“已点击 立即领取”“第1轮扫描完成”之类的信息。如果没有日志多半是脚本被页面本身的过滤规则拦截了或者你粘贴时不小心贴到了“Sources”面板里切回Console重新来一遍即可。3.3 第三步运行结果观察与二次确认脚本跑完不代表结束你还要人工确认一下不然容易白干。怎么确认两个维度。第一个维度是看页面上的按钮状态是否发生了变化。领取成功的按钮通常会变成“已领取”“已完成”之类的灰色不可点状态或者干脆从页面上消失。你如果看到一排按钮都变成了灰色说明脚本是真的干活了。第二个维度是看B站后台的收益记录或激励账单。进入收益明细页面确认刚才那一笔奖励已经进入账户。这里我特别建议养成“脚本跑完必看账单”的习惯因为偶尔会遇到点击事件触发了但后端接口校验失败的情况这时按钮确实变了钱却没到账只有看账单才能发现问题。3.4 进阶在iframe嵌套页面里怎么处理B站后台有一部分页面尤其是活动页和游戏激励页采用的是iframe嵌套结构。你看到的“领取”按钮其实并不在顶层页面的DOM里而在某个iframe内部。这时候直接运行基础版脚本扫描的是顶层document当然什么都找不到。解决办法也很直观先获取iframe再进入iframe的contentDocument里去找按钮。同源iframe是可以直接访问的下面这段代码演示了如何遍历所有iframe并执行点击const totalClick []; const frames Array.from(document.querySelectorAll(iframe)); for (const frame of frames) { try { const doc frame.contentDocument; if (!doc) continue; const buttons Array.from(doc.querySelectorAll(button)); for (const btn of buttons) { const text (btn.textContent || ).trim(); if (/立即领取|领取奖励/.test(text)) { btn.click(); totalClick.push(text); console.log([iframe内点击], text); } } } catch (e) { console.warn(跨域iframe无法访问跳过, e); } } console.log(iframe内共点击, totalClick.length, 个按钮);遇到跨域iframe时会报SecurityError这属于浏览器的安全机制正常情况B站自己的页面都是同域的不太会遇到。如果真的遇到了说明你的脚本被限制在了一个隔离的框架里那就只能手动处理了。4. 踩坑实录常见问题与排查技巧4.1 元素找不到脚本没反应这是最高频的问题。脚本贴进去回车控制台安静如鸡一个日志都没有。或者日志确实输出了“没有找到可领取的按钮”这时候怎么办先检查页面状态。是不是按钮还没渲染出来很多领奖页面的数据请求是异步的打开页面那一刻按钮并不存在需要等一两秒。解决方法就是手动等几秒再运行或者直接用前面写的轮询版脚本让脚本自己等。其次是检查匹配文案是否对得上。虽然B站后台大部分领取按钮都叫“领取”但也有个别页面写的是“领取奖励”的变体比如“领取贝壳”“领取金瓜子”“确认领取”这时候基础版的正则可能会漏掉。你可以临时在控制台执行一行代码把页面所有按钮文字打印出来Array.from(document.querySelectorAll(button)).map(b b.textContent.trim())这样你就能看到页面上到底有哪些按钮文案然后对症下药修改正则。4.2 点击没效果按钮状态不变比找不到更让人抓狂的是点完了没反应。点击事件触发了console日志也打印了但页面没有任何变化。这种情况大概率是按钮绑定的不是原生click事件而是mousedown或者pointerdown事件。原因是很多现代前端框架比如Vue、React在高阶组件里为了更快的响应速度会监听pointerdown而不是click。你用el.click()触发的是click事件但按钮真正监听的事件压根没被触发自然就没反应。解决思路有三种。第一种是改用dispatchEvent派发完整的事件序列先mousedown再mousedown对应的mouseup最后click。第二种是直接触发pointerdown事件const event new Event(pointerdown, { bubbles: true }); btn.dispatchEvent(event);第三种最实用与其模拟点击不如直接调用按钮绑定的JS方法。如果页面是用Vue写的你通常可以通过btn.__vue__来访问组件实例然后调用它的方法。不过我一般不建议普通用户走到这一步优先试第一种和第二种就好。4.3 页面刷新导致脚本中断B站有些领奖按钮点击之后会触发一次页面刷新脚本一刷新就断掉了后面的奖励还没来得及领。这个问题在多个连续领取的场景下特别常见。我的处理办法是分两段走。第一段先把所有可领取按钮的标识记录下来比如按钮在DOM里的索引位置或文案刷新完成后第二段脚本针对剩下的按钮继续执行。简单粗暴的版本就是过一会儿再手动重跑一次脚本不追求一次全领完。还有一种变体问题是点击之后跳到了新的Tab或者新的页面原页面被关闭。这种情况基本不可能保持脚本运行了只能重新打开页面再跑一次。反正这种操作本质上是低频手动任务多跑一次也不麻烦。4.4 被风控或验证码拦住了怎么办这里要先提醒一句自动领取自己的平台奖励本身是合理需求但如果脚本在极短时间内高频点击、一天之内反复触发几十次平台的风控系统确实有可能介入弹验证码甚至暂时限制领取。我在实测中也遇到过两次。我的态度是脚本是效率工具不是刷量外挂。正常的使用节奏是“一周一次到两次每次把当前该领的领完”千万不要做成定时器全自动每5分钟跑一次。如果遇到验证码老老实实手动验证验证完之后减少操作频率一般不会有后续问题。另外提醒一点控制台里不要去做任何涉及修改接口参数、篡改数据、绕过支付之类的操作那是明确的违规行为轻则封号重则承担法律责任。我们写自动领奖脚本的目的是为了把该领的钱顺利领回来不是研究怎么薅平台。4.5 常见问题速查表现象可能原因解决方案脚本运行无日志页面未加载完成或选择器不匹配等待后重跑先打印按钮文案核对点击后无变化按钮监听pointerdown而非click派发pointerdown事件只领到一部分页面动态分页加载使用轮询加强版脚本iframe里的按钮点不到按钮在iframe内部遍历contentDocument连续执行弹出验证码触发风控降低频率手动验证刷新后脚本中断按钮点击触发了跳转重开页面重新执行5. 扩展玩法与最后的心得5.1 从控制台脚本到油猴脚本的迁移虽然标题主打“无需油猴脚本”但如果你确实觉得这个功能好用想让它以后自动运行迁移到油猴也就是几分钟的事。油猴脚本的核心就是一个用户脚本声明块把控制台代码再包一层就行。// UserScript // name B站自动领取创作激励 // namespace https://your-site.example/ // version 1.0 // description 自动点击B站领奖页面的领取按钮 // match https://member.bilibili.com/* // match https://*.bilibili.com/* // grant none // /UserScript (function () { use strict; // 把之前的轮询脚本原样放到这里即可 // 建议加上延迟执行等页面完全加载 window.addEventListener(load, function () { setTimeout(autoClaim, 2000); }); })();注意match的匹配规则要覆盖你常用的后台地址。设置好之后每次进入对应页面脚本会在2秒后自动开始扫描。这样你就同时拿到了“控制台免安装”和“油猴自动化”两种姿势按场景换着用。5.2 还可以自动化的B站后台操作顺着这个思路B站后台其实还有很多类似的“机械性点击”操作可以自动化。比如定期清空消息通知、一键批量领取任务奖励、自动完成每日签到这些本质上都是“在合适的页面找到合适的按钮点一下”。你只需要把脚本里的正则关键词换一换比如把“领取”换成“签到”一个全新的自动化脚本就诞生了。我个人的习惯是维护一个本地脚本库每个站点一个文件里面分门别类放着各种小工具。用到的时候打开控制台复制粘贴完事。这种方式比到处找现成油猴脚本靠谱得多因为你最懂自己的需求出了问题也知道怎么改。5.3 关于自动领取我个人的几点体会最后再分享一点我自己踩过坑之后的感悟。第一写自动化脚本之前一定要先手动把流程完整走一遍亲眼看清楚按钮长什么样、点击之后有什么反应再开始写代码。跳过这一步的人一半以上的时间都花在“为什么脚本没反应”的排查上。第二脚本要尽量做得“克制”。能匹配一个按钮就匹配一个按钮能不轮询就不轮询避免搞出一套失控的自动机器。自动化的意义是节省你的时间不是让你提心吊胆地盯着它跑所以稳定和安全始终是第一位的。第三也是最重要的一点这类自动领奖脚本本质上是“锦上添花”它不能帮你提升内容质量也不能让不达标的激励额变多。真正让创作者激励计划有价值的永远是你的视频本身。把脚本当作效率工具用就好别指望它能改变创作的底层逻辑。脚本写出来就是为了让你省心的。如果你在用的过程中遇到页面改版导致匹配失效或者发现了更好的通用匹配规则欢迎按这个思路自己迭代一版。控制台里的世界很自由折腾本身就是乐趣。
返回列表