Bilibili 账号已注销修正

修正Bilibili 账户已注销的主页链接,修改为 https://www.bilibili.com/list/$UID

< 脚本 Bilibili 账号已注销修正 的反馈

评价:一般 - 脚本能用,但还有一些问题

§
发布于:2025-10-01

这段 userscript 在 search.bilibili.com 遇到账号已注销,会不停的将已恢复的账号重复添加,比如变成《账号已注销 MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL MmaKJ4AiL》是哪里出了问题,该如何修改

Gemini 2.5 Pro:您好,您提供的这个UserScript脚本出现问题的原因在于,它使用了一个setInterval定时器,每3秒钟会重新执行一次检查和修改逻辑(tick函数)。

search.bilibili.com页面,当脚本第一次找到“账号已注销”的链接并修正后,由于没有对已修正的元素进行标记,3秒后下一次定时器触发时,它会再次找到同一个元素并试图再次修正,导致了ID被重复添加的问题。

问题根源

  1. 重复执行setInterval(tick, 3000)导致processLinks()handleElement()函数被反复调用。
  2. 缺少状态标记:脚本在修改了一个DOM元素后,没有“记住”这个元素已经被修改过。因此,下一次执行时,它会把已经修改过的内容(例如“账号已注销MmaKJ4AiL”)作为输入,再次进行处理,从而导致逻辑错误和重复添加。

如何修改

最稳定和常见的解决方法是,在第一次成功处理一个元素后,给它添加一个自定义的data-属性作为标记。在下一次执行时,首先检查该元素是否已有这个标记,如果已经存在,就跳过它。

这正是脚本中处理评论区(processComments函数)时所采用的模式(使用data-processed属性),我们只需将这个模式应用到处理普通链接的handleElement函数中即可。

修正后的脚本

这是完整的修正后脚本。主要的改动在handleElement函数中:我在函数开头增加了检查标记的逻辑,并在成功处理后添加标记

// ==UserScript==
// @name         Bilibili 账号已注销修正
// @name:zh-CN   Bilibili 账号已注销修正
// @namespace    http://tampermonkey.net/
// @version      2.2.3
// @license      MIT
// @description  修正Bilibili 账户已注销的主页链接,修改为 https://www.bilibili.com/list/$UID
// @description:zh-CN  修正Bilibili 账户已注销的主页链接,修改为 https://www.bilibili.com/list/$UID
// @author       Kaesinol (-Modified-)
// @match        https://*.bilibili.com/*
// @grant        none
// @run-at       document-end
// @downloadURL https://update.gf.qytechs.cn/scripts/528706/Bilibili%20%E8%B4%A6%E5%8F%B7%E5%B7%B2%E6%B3%A8%E9%94%80%E4%BF%AE%E6%AD%A3.user.js
// @updateURL https://update.gf.qytechs.cn/scripts/528706/Bilibili%20%E8%B4%A6%E5%8F%B7%E5%B7%B2%E6%B3%A8%E9%94%80%E4%BF%AE%E6%AD%A3.meta.js
// ==/UserScript==

// https://github.com/the1812/Bilibili-Evolved/discussions/4804#discussioncomment-10513931
(function () {
    'use strict';
    function processLinks() {
        const rules = {
            "space\.bilibili\.com\/\\d+\/favlist": {
                query: "div.bili-video-card__subtitle a"
            },
            "bilibili.com\/(video|list)\/": {
                type: "abnormal",
                query: ".up-detail-top a"
            },
            "search\.bilibili\.com": {
                query: ".bili-video-card__info--owner"
            },
        };

        // 遍历执行
        Object.entries(rules).forEach(([host, { query, type }]) => {
            if (RegExp(host).test(location.href)) {
                document.querySelectorAll(query).forEach(el => handleElement(el, type));
            }
        });

    }
    function base64(n) {
        n = BigInt(n); // 保证是 BigInt
        const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
        let res = "";
        while (n > 0n) {
            res = chars[Number(n % 64n)] + res;
            n /= 64n;
        }
        return res || "A";
    }

    // --- 修改后的函数 ---
    function handleElement(tag, type = "normal") {
        // 【新增】检查元素是否已经被处理过,如果处理过则直接跳过
        if (tag.dataset.uidFixed === 'true') {
            return;
        }

        let text = null;
        let regular = true;
        if (['space.bilibili.com', 'search.bilibili.com'].includes(location.hostname)) {
            text = tag.textContent.split(" ")[0];
            regular = false;
        } else {
            text = tag.text;
        }
        if (text.trim() === "账号已注销") {
            const match = tag.href.match(/\/(\d+)\??/);
            // 增加一个安全检查,如果匹配失败则不继续执行
            if (!match) return;

            tag.style.fontStyle = "italic";
            if (regular)
                tag.text += base64(match[1]);
            else
                tag.textContent = tag.textContent.replace("账号已注销", "账号已注销" + base64(match[1]));

            if (type == "normal") {
                tag.href = `https://www.bilibili.com/list/${match[1]}`;
            } else {
                tag.addEventListener('click', function (event) {
                    event.preventDefault(); // 阻止默认跳转行为
                    window.open(`https://www.bilibili.com/list/${match[1]}`, '_blank');
                });
            }
            // 【新增】处理完成后,给元素添加一个标记
            tag.dataset.uidFixed = 'true';
        }
    }
    // --- 修改结束 ---

    function processCommentRenderers(elements) {
        elements.forEach(renderer => {
            const bili = renderer.shadowRoot.querySelector('bili-comment-renderer');
            if (!bili || !bili.shadowRoot) return;
            const userInfo = bili.shadowRoot.querySelector('bili-comment-user-info');
            if (!userInfo || !userInfo.shadowRoot) return;
            const user = userInfo.shadowRoot.querySelector('#user-name a');
            if (user) handleElement(user);

            const replies = renderer.shadowRoot.querySelector('bili-comment-replies-renderer');
            if (!replies || !replies.shadowRoot || !replies.shadowRoot.textContent.trim()) {
                renderer.setAttribute('data-processed', 'true');
                return;
            }

            const replyNodes = replies.shadowRoot.querySelectorAll('bili-comment-reply-renderer');
            replyNodes.forEach(reply => {
                const rUserShadow = reply.shadowRoot.querySelector('bili-comment-user-info');
                if (rUserShadow && rUserShadow.shadowRoot) {
                     const rUser = rUserShadow.shadowRoot.querySelector('#user-name a');
                     if (rUser) handleElement(rUser);
                }
            });

        });
    }
    function processComments() {
        const startElement = document.querySelector('bili-comments');
        if (startElement && startElement.shadowRoot) {
            const allElements = startElement.shadowRoot.querySelectorAll('bili-comment-thread-renderer:not([data-processed])');
            processCommentRenderers(allElements);
        }
    }
    function tick() {
        processComments();
        processLinks();
    }

    setInterval(tick, 3000);

})();

主要改动总结

  1. handleElement 函数开头增加检查

    if (tag.dataset.uidFixed === 'true') {
        return;
    }
    

    这行代码会检查元素是否有data-uid-fixed="true"这个属性。如果有,说明是已经被我们脚本处理过的元素,函数会立即停止执行,避免重复修改。

  2. handleElement 函数成功处理后增加标记

    tag.dataset.uidFixed = 'true';
    

    当脚本成功修改了链接和文本后,这行代码会给该元素添加上标记,以便下次检查时可以跳过。

  3. (可选优化) 我还将 tag.text 的修改换成了 tag.textContent,这在处理DOM时是更明确和推荐的做法,并为 match 变量增加了安全检查。

将您的旧脚本替换为上面的版本,即可解决在搜索页面重复添加ID的问题。

kaixinol作者
§
发布于:2025-10-02

🤔单独开启本脚本无法复现此问题,是否有其他脚本开启? 麻烦提供有bug出现的网址

发布留言

登录(不可用)以发布留言。

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址