ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用油猴脚本实现B站消息批量清理:原理、开发与多端免登录实践

用油猴脚本实现B站消息批量清理:原理、开发与多端免登录实践 最近总有人在问B站消息列表动不动就几百条红点手动一条条删实在太累有没有什么工具能一键清理网上一搜确实能找到各种“批量清理工具”但很多都要你把账号密码或二维码交给第三方平台。这种工具背后的风险其实很高——你根本不知道它是不是只处理消息还是会顺手拉取私信、改设置、看关注列表。油猴脚本恰好提供了一个更轻、更可控的答案。它运行在浏览器内部能复用你当前已经登录的 B 站会话不需要单独登录一个第三方平台也不需要用脚本作者的服务器。所以类似“B站消息清理助手 v0.2多端免登陆”这类工具本质上不是绕过了 B 站的登录验证而是把“我已经在浏览器里登录过 B 站”这个状态直接复用。真正决定脚本能不能用的不是接口本身而是登录态、删除频率、确认机制和误删边界这几件事。这篇文章会围绕 B 站消息清理这个具体场景讲清楚油猴脚本的运行原理、开发调试思路、一个可扩展的清理助手示例实现以及把它装到多端浏览器时需要注意的问题。就算你之前完全没写过油猴脚本看完以后也能自己动手写一个类似的网页自动化小工具。1. 这篇文章真正要解决的问题先给一个明确判断很多人做“B站消息清理”不是不会写代码而是走了两条高风险的路。第一条路把账号密码发给来路不明的工具站。你以为对方只是帮你一个忙实际上对方拿到的是一个完整账号权限。轻则数据被扒走重则被拿去发动态、刷评论甚至触发平台风控导致封号。第二条路打开浏览器控制台手动粘贴一段从网上复制的脚本。这种脚本往往没有频率控制也没有删除范围限制一个死循环下去可能把私信会话、重要历史通知全清空了而且删除不可恢复。油猴脚本解决的是中间地带的痛点代码都在本地逻辑你能看懂权限边界你能控制。它不需要中间服务器不需要额外登录直接运行在 B 站消息页面里面。删什么、删多少、多久停都由脚本里的代码决定。那这篇文章适合谁读被 B 站消息红点困扰想批量清理自己账号消息的普通用户。想学习油猴插件开发但不知道从哪入手的开发者。正在研究浏览器自动化脚本工程化需要了解免登录、频率控制和配置隔离这类问题的前端爱好者。不适合谁读想批量操作他人账号、想绕过平台限制、想抓取他人隐私的人。这个定位必须先说清楚。消息清理助手处理的对象必须是你自己的账号消息删除确认机制、小批量测试、日志记录这些设计也不是摆设而是为了让工具不至于变成事故现场。2. 油猴脚本的运行原理与“多端免登录”的正确理解2.1 Tampermonkey 到底做了什么油猴是 Tampermonkey 的中文俗称它是一个浏览器扩展负责管理用户脚本UserScript。用户脚本是一种由网页用户自己定义的 JavaScript 文件带有特殊格式的元信息例如在哪些页面运行、需要哪些权限、版本号是多少。没有 Tampermonkey 的时候用户想要在网页上执行自定义 JavaScript通常只能打开开发者工具的控制台手动粘贴代码。这样做的缺点很明显代码不会自动执行页面刷新后效果就没了也无法使用跨域请求、本地存储这类能力。有了 Tampermonkey 以后脚本管理这件事变成了三个环节Tampermonkey 读取脚本头部的元数据块。当浏览器地址栏 URL 符合脚本中的match规则时Tampermonkey 自动把脚本注入到页面中。根据grant声明的权限Tampermonkey 为脚本提供额外的浏览器扩展 API比如跨域请求GM_xmlhttpRequest、本地配置存储GM_setValue/GM_getValue等。一个最简油猴脚本的结构是下面这样的// UserScript // name B站消息清理助手示例 // namespace http://your-local-dev/ // version 0.2 // description 演示用油猴脚本骨架 // author local-dev // match https://message.bilibili.com/* // run-at document-idle // grant none // /UserScript (function () { use strict; console.log(脚本已经在 B 站消息页面运行); })();可以看到match决定了脚本的生效范围。只有 URL 符合https://message.bilibili.com/*时这段代码才会被执行。run-at document-idle则告诉 Tampermonkey在页面 DOM 基本加载完成后运行脚本避免元素还没渲染出来就操作报错。2.2 “多端免登录”是什么不是什么很多用户一看到“免登录”就以为是不需要 B 站账号也能删消息或者脚本保存了某个账号的密码这是理解偏差。B 站消息清理助手所谓的免登录本质上是复用了浏览器当前已经登录的 B 站会话状态。一个直观说法是你在电脑 Chrome 上登录过 B 站这个页面本身就带着你的登录凭证。油猴脚本在同一个页面上下文里运行由页面去请求删除接口时浏览器会自动把带登录凭证的 Cookie 一起发出去。脚本自己并不需要输入账号密码也不需要再去登录一次。把它放到手机浏览器或另一台电脑上也一样只要那个浏览器已经登录了你的 B 站账号并安装了同样的脚本清理操作就能继续执行。这才是“多端”的意义——脚本可以安装在多个浏览器端但账号登录状态仍然是当前浏览器本身持有的。可以用一个表格来做区分方式是否输入 B 站账号密码是否依赖第三方服务器是否复用当前登录态风险等级第三方网页工具通常需要是否高凭证可能被记录自己抓包写脚本不需要否是中容易误删和限流油猴脚本不需要否是中低取决于脚本逻辑所以“免登录”应该被理解成“免去额外登录一个中间平台的成本”而不是“绕过 B 站账号验证”。写脚本时要记住一个底线不要在脚本里保存任何账号、密码或 Cookie 到第三方服务器也不要请求无关域名。这种工具一旦被人加入数据回传逻辑用户是很难从表面看出来的。3. 前置条件与环境准备3.1 准备浏览器和油猴扩展开发和使用油猴脚本第一步是在浏览器中安装 Tampermonkey。Chrome、Edge、Firefox、Safari 等主流浏览器都有对应版本。以 Chrome/Edge 为例直接在扩展商店搜索 Tampermonkey 并添加即可注意认准官方账号避免装到仿冒的脚本管理器。安装完成后浏览器工具栏通常会出现油猴图标。新手最容易踩坑的地方是脚本已经安装了但功能没生效可能是因为扩展没有启用也可能是浏览器处于无痕模式并且没有允许扩展在无痕模式下运行。如果你想严格限制脚本的权限可以从 Tampermonkey 设置面板进入“扩展选项”查看每个脚本的启用状态、授权域名和存储数据。油猴本身并不限制脚本能读到多少页面信息真正决定边界的是脚本代码是否克制。3.2 创建第一个油猴脚本骨架在 Tampermonkey 图标上点击选择“添加新脚本”会进入一个内置编辑器。Tampermonkey 会自动生成一个默认脚本模板删除模板内容后可以粘贴自己的脚本。为了保证脚本只在你需要的地方生效建议把match写得尽量精确。例如只清理 B 站消息相关页面// UserScript // name B站消息清理助手 v0.2 // namespace local-dev // version 0.2 // description 多端浏览器可用的B站消息批量清理助手示例 // author local-dev // match https://message.bilibili.com/* // match https://t.bilibili.com/* // run-at document-idle // grant GM_setValue // grant GM_getValue // /UserScript这里的match是 URL 匹配规则。两个域名分别覆盖 B 站消息中心和个人动态页。如果你只希望它运行在消息页就不需要把个人动态页加进来。权限越小脚本误伤其他页面的可能性就越低。grant GM_setValue和grant GM_getValue用于持久化脚本配置比如你想记住上一次清理到哪个分类、是否处于自动运行状态都可以用这两个 API 实现。它们把数据保存在 Tampermonkey 管理的存储中不会写入到页面 Cookie 里也不会自动同步到其他设备这一点后面会展开说明。如果只是写一个最基础的点击辅助脚本可以把grant设置为none不需要申请任何额外权限。这样更安全但也会失去跨域请求和脚本级存储能力。4. 定位 B 站消息接口与理解删除边界4.1 消息分类与风险在设计消息清理助手之前要先确认你要清理的消息属于什么类型。B 站消息中心里常见的消息类型包括回复我的、我的、收到的赞、系统通知、私信等。不同类型的删除风险差别很大。消息类型是否建议脚本批量清理原因收到的赞可以信息价值低清理风险小回复我的可以但建议先已读可能包含有人认真回复你的内容我的可以但建议先已读不确定是否包含重要讨论系统通知可以多为活动推送和站务通知私信强烈不建议脚本批量处理可能包含重要沟通记录误删不可恢复很多 B 站消息清理工具把私信也纳入一键清理范围这是风险最高的设计。一个消息清理助手应该是“保守删除”的优先清理明显无价值的赞和通知对读过的回复和 提醒做忽略或已读处理而不是一股脑连私信一起删光。4.2 通过开发者工具观察网络请求如果你要写一个高效率的清理助手只靠模拟点击页面按钮可能不够快。更常见的做法是观察网页发起删除请求时调用了哪个接口然后让脚本直接请求这个接口。操作路径可以通过开发者工具完成先在 B 站消息页登录自己的账号。按 F12 打开开发者工具切到 Network 面板。在消息列表中手动点击一次“删除”或“移除”按钮。观察 Network 面板中出现的请求重点关注 POST 类型的 XHR/Fetch 请求。查看请求的 URL、Payload、请求头和响应内容。这一步需要强调B 站接口路径属于网页内部实现随时可能改版调整而且不同账号、不同消息类型的删除接口不一定一致。任何人写脚本时都不应该把某个接口路径当成永久有效的东西。稳妥做法是把它做成配置项而不是硬编码在代码深处。还有一点需要理解网页端删除消息通常需要携带 CSRF 校验信息。CSRF 是一种防止跨站请求伪造的机制B 站网页在请求时往往会读取 Cookie 里某个字段的值或页面中隐藏的 token作为请求参数一起发送。这个过程在你的浏览器环境中是自动完成的脚本只是替你发起了请求。如果你在做彻底清理之前不确定接口删掉的到底是哪一条消息请先只清理一条观察 Network 请求参数里的消息 ID 是否和页面上你点的那条消息对应。确认对应关系以后再设计批量逻辑否则很容易出现“代码逻辑没问题但删错了对象”的惨案。4.3 页面请求与 GM_xmlhttpRequest 的区别如果你在开发者工具里看到删除请求是 POST 到api.bilibili.com或类似域名那么在油猴脚本中不一定能直接使用页面里的普通fetch或XMLHttpRequest去调用。因为页面脚本受到同源策略限制不同域名之间默认不能自由通信。油猴脚本之所以强大是因为它可以使用GM_xmlhttpRequest这个扩展 API 来发起跨域请求并且在发起请求时可以选择携带当前浏览器域的 Cookie。但使用它有一个前提脚本头部的元数据中需要声明grant GM_xmlhttpRequest并用connect写明允许连接的目标域名。下面是一个结构示例// UserScript // name B站消息清理助手 v0.2接口请求模式 // namespace local-dev // version 0.2 // description 演示封装 GM_xmlhttpRequest 的请求骨架 // match https://message.bilibili.com/* // grant GM_xmlhttpRequest // connect api.bilibili.com // /UserScript (function () { use strict; function requestDelete(url, data) { return new Promise((resolve, reject) { GM_xmlhttpRequest({ method: POST, url: url, data: data, credentials: include, onload: (res) { try { resolve(JSON.parse(res.responseText)); } catch (e) { reject(new Error(响应解析失败)); } }, onerror: (err) reject(err) }); }); } window.BiliCleaner { requestDelete }; })();注意这里只是一个请求骨架url和data都应由你通过开发者工具实际抓包得到。直接照搬一个臆想的接口路径或者传一个猜出来的参数很可能返回鉴权失败或参数错误。开发时请先小规模测试。5. 消息清理助手 v0.2 的完整示例实现5.1 设计目标与版本实现思路一个“v0.2”风格的 B 站消息清理助手相比最初的 CtrlC、CtrlV 脚本应该解决三个问题给清理过程一个明确的范围和停止条件避免死循环。把删除频率控制在一个相对安全的节奏降低被风控的概率。让非技术用户也能安装使用而不仅仅是在控制台粘贴的玩具。下面这个示例实现采用“两种模式结合”的思路默认模式是基于页面 DOM 的辅助点击适合普通用户进阶模式是封装接口请求适合能自己抓包的用户。为了演示方便文章代码中的选择器和接口路径都属于占位性的通用写法需要你根据自己的浏览器实际结构调整。5.2 脚本元数据与配置区// UserScript // name B站消息清理助手 v0.2 // namespace local-dev // version 0.2 // description 批量清理B站当前账号消息/红点多端浏览器可安装复用本机登录态 // author local-dev // match https://message.bilibili.com/* // run-at document-idle // grant GM_setValue // grant GM_getValue // grant GM_xmlhttpRequest // connect api.bilibili.com // /UserScript (function () { use strict; const DEFAULT_CONFIG { maxDeleteCount: 20, delayMinMs: 1200, delayMaxMs: 2500, clickMode: true, apiMode: false, deleteEndpoint: , csrfToken: , onlyCurrentModule: true }; function loadConfig() { const saved GM_getValue(biliCleanerConfig, ); if (!saved) return { ...DEFAULT_CONFIG }; try { return { ...DEFAULT_CONFIG, ...JSON.parse(saved) }; } catch (e) { return { ...DEFAULT_CONFIG }; } } function saveConfig(config) { GM_setValue(biliCleanerConfig, JSON.stringify(config)); } window.BiliCleanerConfig loadConfig(); window.BiliCleanerSaveConfig saveConfig; })();配置区是整个脚本的“安全阀门”。maxDeleteCount控制单次最多删除多少条新手不建议直接设成无限大。delayMinMs和delayMaxMs控制两次点击之间的随机等待时间。加入随机延迟的目的是让操作节奏更像人手点击也能给接口留出处理时间。clickMode表示安全点击模式apiMode表示接口请求模式。默认建议开启clickMode因为点击页面真实按钮时页面自身的登录校验、参数组装、前端提示都还在出错概率低很多。接口请求模式只适合能自己抓包、愿意承担更高风险的进阶用户。5.3 核心清理逻辑安全点击模式安全点击模式的核心思路很简单在 B 站消息页当前可见的消息列表中找到类似“删除”或“移除”的按钮逐个点击每点击一次等待一段随机时间当找不到更多按钮或达到上限时停止。// 文件bili-cleaner-click-mode.js // 这个文件是脚本主体的一部分粘贴时放在配置区之后。 function sleepRandom(minMs, maxMs) { const ms Math.floor(Math.random() * (maxMs - minMs 1)) minMs; return new Promise((resolve) setTimeout(resolve, ms)); } function isButtonVisible(el) { const rect el.getBoundingClientRect(); const style window.getComputedStyle(el); return rect.width 0 rect.height 0 style.visibility ! hidden style.display ! none; } function findDeleteButton(container) { const candidates container.querySelectorAll(button, span, div, li); for (const el of candidates) { const text (el.textContent || ).replace(/\s/g, ).trim(); if (text 删除 || text 移除 || text 删除消息) { if (el.offsetWidth 200 el.offsetHeight 80 isButtonVisible(el)) { return el; } } } return null; } async function runClickCleaner(moduleContainer, maxCount) { let deletedCount 0; while (deletedCount maxCount) { const deleteBtn findDeleteButton(moduleContainer); if (!deleteBtn) break; deleteBtn.click(); deletedCount 1; await sleepRandom(window.BiliCleanerConfig.delayMinMs, window.BiliCleanerConfig.delayMaxMs); const confirmBtn findConfirmButton(document); if (confirmBtn) { confirmBtn.click(); await sleepRandom(500, 1200); } } return deletedCount; } function findConfirmButton(root) { const dialog root.querySelector(.confirm-btn, .primary-btn, [roledialog] button); return dialog isButtonVisible(dialog) ? dialog : null; }这段代码的关键点在于每次点击以后先等待随机时间再去寻找可能的二次确认按钮。大部分删除功能在点击后会出现弹窗确认如果脚本直接跳过确认页面上的消息可能不会真正被删除。findDeleteButton中通过文本内容和元素尺寸双重过滤是为了避免误点页面顶部导航栏中的其他“删除”入口。B 站页面结构可能变化文本匹配方案不一定是最终方案你可以打开控制台查看真实节点后把选择器替换成更精确的>// 文件bili-cleaner-panel.js function createPanel() { const panel document.createElement(div); panel.id bili-cleaner-panel; panel.style.cssText position:fixed;right:20px;bottom:20px;z-index:99999;width:240px; background:#fff;border:1px solid #e3e5e7;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.12); padding:12px;font-size:14px;line-height:1.6;; panel.innerHTML div stylefont-weight:600;margin-bottom:8px;B站消息清理助手/div label styledisplay:block;margin-bottom:6px; 单次最大清理数 input idcleaner-max-count typenumber value${window.BiliCleanerConfig.maxDeleteCount} stylewidth:90px;margin-left:8px; / /label button idcleaner-run-btn stylebackground:#fb7299;border:none;color:#fff;padding:6px 12px;border-radius:4px;cursor:pointer;清理当前分类/button div idcleaner-status stylemargin-top:8px;color:#666;/div ; document.body.appendChild(panel); document.getElementById(cleaner-run-btn).addEventListener(click, async () { const statusEl document.getElementById(cleaner-status); const maxCount Number(document.getElementById(cleaner-max-count).value) || 10; const moduleContainer findCurrentModuleContainer(); if (!moduleContainer) { statusEl.textContent 未找到消息列表容器; return; } statusEl.textContent 清理中...; const deleted await runClickCleaner(moduleContainer, maxCount); statusEl.textContent 本次清理 ${deleted} 条; }); } function findCurrentModuleContainer() { const modules document.querySelectorAll(.message-list, .msg-list, .list-container); for (const module of modules) { if (module.offsetWidth 0 || module.getBoundingClientRect().width 0) { return module; } } return null; } createPanel();这里的悬浮面板不监听全局事件只在上一步创建的面板范围内绑定按钮事件避免脚本和 B 站原有的事件相互干扰。前端页面是单页应用时切分类后 DOM 会被重新渲染悬浮面板可能被页面覆盖但通常消息页面主体不会随意清空右下角区域所以简单方案已经够用。5.5 从安装到运行的完整闭环把以上代码合并到同一个脚本后整个清理流程如下用户打开message.bilibili.com消息页。Tampermonkey 自动注入脚本创建右下角面板。用户手动点击页面中的某个消息分类选项卡让列表展示想清理的消息。回到面板点击“清理当前分类”。脚本在当前可见列表中查找删除按钮每找到一个就点击一次随机等待后继续找下一个。当找不到按钮、数量达到上限或用户手动停止时清理结束。这样设计的优点是普通用户不需要关心任何接口细节浏览器已经登录什么账号脚本就清理什么账号。缺点也很明显它依赖页面 DOM 结构。B 站改版后按钮文本变了、容器类名变了脚本就可能失效。这种失效不是 bug而是网页自动化脚本的正常生命周期。6. 安装、运行与效果验证6.1 安装步骤这里给出完整安装步骤按顺序执行即可。浏览器安装 Tampermonkey 扩展。点击浏览器工具栏的 Tampermonkey 图标选择“添加新脚本”。删除模板内容粘贴上面合并后的脚本代码。按 CtrlS 保存脚本。打开 B 站消息页https://message.bilibili.com确认页面右下角出现悬浮面板。如果页面右下角没有悬浮面板可以点击 Tampermonkey 图标确认脚本状态是否处于启用状态再查看浏览器地址栏 URL 是否满足match规则。6.2 运行前要做的三项检查第一次运行清理脚本前不要直接设置单次清理 5000 条。正确做法是先把maxDeleteCount设为 1 或 2把删除延迟调到 2000 毫秒以上运行一次观察过程是否正常。具体来说有三项检查确认当前浏览器登录的是你自己的 B 站账号不是别人借用的账号。确认当前选中的消息分类里没有重要内容。如果里面有重要通知、朋友回复或重要私信请先手动已读或收藏。确认悬浮面板上的单次最大清理数不影响其他消息模块尤其不要把“私信”类消息纳入清理范围。如果你使用的是接口请求模式还要先单独执行一次接口调用检查响应里是否返回失败原因。如果出现参数错误、csrf 校验失败、请求频率过快等提示请先修正再批量执行。6.3 如何判断清理成功运行中可以在页面看到两类反馈面板上的状态文字会从“清理中...”变成“本次清理 N 条”。当前消息分类下部分消息消失或列表数量明显减少。真正判断清理成功的标准不是看状态里的数字而是刷新页面以后确认这个分类的红点和未读数已经消失并且同账号下其他重要消息没有被误删。如果刷新后消息又回来了说明刚才的删除可能只是移除了未读状态或前端隐藏了条目并没有真正删除后台消息如果刷新后其他分类也变空了说明脚本的匹配范围出了问题需要立刻停止并通过 B 站的消息回收功能尝试恢复。还有一点要格外小心如果你在运行过程中看到控制台提示失败但页面上的按钮一直在被点击实际后台可能一条都没删掉。此时应该先暂停脚本查看接口响应或浏览器 Network 面板中的请求是否真的发出而不是盲目增加清理次数。7. 常见问题与排查思路油猴脚本在别人的电脑上能用在自己的浏览器里却失效这是最让新手困惑的问题。我把常见问题整理成一张排查表。问题现象可能原因排查方式解决方案脚本没状态图标页面无悬浮面板油猴扩展未启用或 match 不匹配点击油猴图标检查启用状态确认 URL 是否符合 match启用扩展修正 match 匹配地址面板出现但点击清理按钮无反应当前页面没有消息列表或容器选择器未命中在控制台执行 document.querySelectorAll(.msg-list) 查看数量用开发者工具查看真实 DOM 结构替换选择器点击删除按钮后消息仍在删除逻辑只点击了未读标记没有触发真正删除对照手动删除时按钮文案和弹窗差异调整删除按钮文本匹配规则清理几条后停止状态显示 0页面找不到更多按钮或列表是虚拟滚动打开控制台观察实际 DOM 节点数滚动列表加载更多后重新执行运行时报跨域错误代码用了 GM_xmlhttpRequest 但缺少 connect查看油猴控制台错误在 connect 添加对应域名接口请求返回 csrf 校验失败请求参数中缺少有效 token检查抓包请求的 csrf 参数来源从 Cookie 中读取 bili_jct 或页面源码解析运行后出现验证码或风控提示删除频率过高或行为特征异常立刻停止脚本延长延迟降低单次删除数量间隔几小时再试其他浏览器需要重新设置油猴脚本配置默认不跨端自动同步检查 GM_setValue 存储在不同浏览器并不共享手动导出配置或使用油猴同步功能这里要特别提醒第 7 种情况很多用户以为只要在电脑上配置好手机浏览器打开立刻就能用。实际上Tampermonkey 的GM_setValue/GM_getValue存储是跟随特定浏览器和脚本位置的不会因为你安装了同一个脚本就自动同步。如果你想在多端复用同样的配置要么在每个端手动设置要么通过油猴自带的同步功能如果开启同步脚本数据。所谓“多端免登录”指的是每个端都要保持 B 站账号登录而不是配置天然互通。8. 最佳实践与工程建议如果要把 B 站消息清理助手从自用脚本变成可以长期维护的小工具有几个原则值得遵守。第一个原则是“精确匹配最小授权”。match范围不要写成https://*/*那样脚本会在你登录的所有网站都生效出问题的面就太大了。建议只匹配https://message.bilibili.com/*和必要的相关页面。grant也需要按需声明不需要跨域请求就不要随便加GM_xmlhttpRequest。第二个原则是“先已读后删除再考虑批量”。B 站消息中心的很多“打扰”其实通过已读操作就能消除。已读不会产生不可逆后果删除一旦执行很难恢复。脚本默认的清理策略建议把“已读”作为第一动作。如果你已经看完某条提醒确认无价值再让脚本执行删除。这个原则看起来很保守却能在长期使用中避免很多自己都记不清的损失。第三个原则是“使用有上限和随机延迟的频率控制”。千万不要在一个循环里无脑连续点击几百次。服务端限流策略通常包含频率检测高频操作会触发验证码甚至临时封禁。与其赌运气不如把单次上限设置为 20—50 条延迟设置在 1—3 秒随机值。执行过程中如果发现开始出现失败响应脚本应该自动指数退避也就是把下次等待时间翻倍而不是继续强跑。第四个原则是“配置和代码分离参数可调整”。很多网上的油猴脚本把删除数量、延迟时间、接口地址写死在业务逻辑深处用户想改一个数字都要在代码里找半天。更合适的方式是把配置集中在脚本头部的配置区并通过 GM_setValue 持久化。这样以后修改只需要调整配置项代码主体保持稳定。第五个原则是“日志记录不可省”。在开发阶段脚本每执行一次操作都应该在控制台输出一行 log内容包括时间、动作类型、目标元素文本、执行结果。日志不用做得多复杂但对排查“为什么删了 100 条只成功 10 条”这类问题极有帮助。也不要只写console.log(deleted)这种没有上下文的日志要写类似[2025-01-01 12:00:00] deleted item, idxxx, remain99的完整信息。第六个原则是“绝对不做数据回传”。自用也好分享给他人也罢脚本都不应该向除 B 站外的任何服务器发送数据。你在网页里能读取到的所有内容都是用户隐私包括消息内容、用户 ID、点赞记录。一旦脚本作者在代码中加入数据回传逻辑普通用户从代码表面很难发现。所以如果你打算使用别人写的清理工具一定要先通读脚本代码尤其是GM_xmlhttpRequest、XMLHttpRequest、fetch相关调用是否指向了无关域名。如果你的脚本要让团队或社群使用还应该在脚本头部注释中写清楚使用边界仅允许清理本人账号消息删除结果不可恢复请在测试账号环境中验证使用者风险自负。这看起来像免责声明实际上也是开发者在提醒自己工具解决的是“重复操作累人”的问题不是“突破平台规则”的问题。9. 延伸已经会写消息清理助手下一步可以做什么当你把 B 站消息清理助手这个例子完整跑通后可以明显感受到油猴脚本的开发门槛比想象中低。它不需要重新搭一个项目不需要启动后端服务也不需要申请复杂的 OAuth 授权。你只需要理解页面结构、看清网络请求、写出安全边界明确的 JavaScript就能拥有一个真正属于自己的浏览器增强工具。你会慢慢发现这类脚本的通用套路其实是固定的确定脚本只应该运行在哪些页面。通过开发者工具找到页面核心操作对应的 DOM 或接口。把操作拆成“获取列表—判断条件—执行动作—节流等待—统计结果”。给每个危险动作设置确认机制和数量上限。把敏感操作和明文凭证隔离拒绝一切数据回传。用这个思路你完全可以继续扩展到 B 站其他场景比如可见消息的本地导出、关注列表的批量备份、动态页的可读性优化等。你也可以把同一个套路用在其他内容平台但前提仍然是所有操作都限于你本人账号和合法授权范围。脚本工具的真正价值不在于“一键清空”这个爽感而在于它把你从重复劳动中解放出来同时把账号控制权留在自己手里。安装、测试、小批量验证、保持代码可读这四个动作做好油猴脚本就能长期成为你的效率工具箱里最顺手的那一件。
返回列表