吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2|回复: 0
收起左侧

[其他原创] 【油猴脚本】bilibili哔哩哔哩广告全面屏蔽 & 导航精简

[复制链接]
MRBANK 发表于 2026-8-28 10:13
插件设置:
2026-08-28_100152.png

屏蔽后效果:
2026-08-28_101044.jpg

直接上脚本:
// ==UserScript==
// @name         哔哩哔哩广告全面屏蔽 & 导航精简
// @version      3.2
// @description  屏蔽视频底部广告/活动横幅、侧边栏广告及底部推广、推荐流广告视频、小型广告卡片、视频底部标签、首页轮播、花生平台广告、直播页广告等,完全避开评论区,带UI开关控制,并支持导航栏精简
// @author       MRBANK
// @match        *://*.bilibili.com/*
// @icon         https://www.bilibili.com/favicon.ico
// @grant        GM_registerMenuCommand
// @run-at       document-end
// ==/UserScript==
// @downloadURL  https://cdn.jsdelivr.net/gh/hangzai1667/my-tampermonkey-scripts@main/bilibili.user.js
// @updateURL    https://cdn.jsdelivr.net/gh/hangzai1667/my-tampermonkey-scripts@main/bilibili.user.js
(function() {
    'use strict';

    // ================= 配置管理 =================
    const CONFIG_KEY = 'bilibili_purifier_config';
    const defaultConfig = {
        bottomBanner: true,    // 1. 视频底部广告横幅
        sideAd: true,          // 2. 侧边栏广告(右侧浮动)
        rightBottomAd: true,   // 3. 侧边栏底部推广
        smallAdCard: true,     // 4. 小型广告卡片
        feedAdVideo: true,     // 5. 推荐流广告视频
        videoTag: true,        // 6. 视频底部标签
        activityBanner: true,  // 7. 视频底部活动横幅
        homeCarouselAd: false, // 8. 首页轮播广告(默认关闭)
        huashengBanner: true,  // 9. 投稿菜单花生横幅
        btnAd: true,           // 10. 创作页按钮广告
        liveBannerAd: true,    // 11. 直播间轮播广告

        // --- 导航栏精简 ---
        hideAnime: false,      // 番剧
        hideLive: false,       // 直播
        hideGameCenter: false, // 游戏中心
        hideMall: false,       // 会员购
        hideManga: false,      // 漫画
        hideMatch: false,      // 赛事
        hideDownload: false,   // 下载客户端
        hideVip: false         // 大会员
    };

    const configStructure = [
        {
            groupName: "广告与推广",
            items: [
                { key: 'bottomBanner', label: '视频底部广告横幅' },
                { key: 'sideAd', label: '侧边栏广告(浮动)' },
                { key: 'rightBottomAd', label: '侧边栏底部推广' },
                { key: 'smallAdCard', label: '小型广告卡片' },
                { key: 'feedAdVideo', label: '推荐流广告视频' },
                { key: 'homeCarouselAd', label: '首页轮播广告' },
                { key: 'huashengBanner', label: '投稿菜单花生横幅' },
                { key: 'btnAd', label: '创作页按钮广告' },
                { key: 'liveBannerAd', label: '直播间轮播广告' }
            ]
        },
        {
            groupName: "页面元素精简",
            items: [
                { key: 'videoTag', label: '视频底部标签' },
                { key: 'activityBanner', label: '视频底部活动横幅' }
            ]
        },
        {
            groupName: "导航栏精简 (左侧+右侧)",
            items: [
                { key: 'hideAnime', label: '隐藏 番剧' },
                { key: 'hideLive', label: '隐藏 直播' },
                { key: 'hideGameCenter', label: '隐藏 游戏中心' },
                { key: 'hideMall', label: '隐藏 会员购' },
                { key: 'hideManga', label: '隐藏 漫画' },
                { key: 'hideMatch', label: '隐藏 赛事' },
                { key: 'hideDownload', label: '隐藏 下载客户端' },
                { key: 'hideVip', label: '隐藏 大会员' }
            ]
        }
    ];

    function getConfig() {
        let saved = localStorage.getItem(CONFIG_KEY);
        if (saved) {
            try {
                let oldCfg = JSON.parse(saved);
                if (oldCfg.leftBanner !== undefined && oldCfg.bottomBanner === undefined) {
                    oldCfg.bottomBanner = oldCfg.leftBanner;
                    delete oldCfg.leftBanner;
                    localStorage.setItem(CONFIG_KEY, JSON.stringify(oldCfg));
                }
                return {...defaultConfig, ...oldCfg};
            }
            catch(e) { return {...defaultConfig}; }
        }
        return {...defaultConfig};
    }

    function saveConfig(cfg) {
        localStorage.setItem(CONFIG_KEY, JSON.stringify(cfg));
    }

    // ================= 油猴菜单与设置 UI =================
    let isPanelOpen = false;
    let needReload = false;

    function openSettingsPanel() {
        if (isPanelOpen) return;
        isPanelOpen = true;
        needReload = false;

        const style = document.createElement('style');
        style.id = 'bp-settings-style';
        style.textContent = `
            #bp-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.4); z-index: 999998; display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
            #bp-modal { background: #fff; width: 380px; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.15); overflow: hidden; display: flex; flex-direction: column; }
            #bp-header { display: flex; justify-content: space-between; align-items: center; padding: 15px 20px; border-bottom: 1px solid #e8e8e8; }
            #bp-header h3 { margin: 0; font-size: 16px; color: #333; }
            #bp-close-btn { background: none; border: none; font-size: 20px; color: #999; cursor: pointer; line-height: 1; padding: 0; }
            #bp-close-btn:hover { color: #333; }
            #bp-body { padding: 10px 0; max-height: 70vh; overflow-y: auto; }
            .bp-group-title { padding: 10px 20px 5px; margin: 0; font-size: 13px; color: #888; font-weight: 500; }
            .bp-switch-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 20px; font-size: 14px; color: #333; transition: background 0.2s; }
            .bp-switch-row:hover { background: #fff1f5; }
            .bp-switch { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; }
            .bp-switch input { opacity: 0; width: 0; height: 0; }
            .bp-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .3s; border-radius: 22px; }
            .bp-slider:before { position: absolute; content: ""; height: 16px; width: 16px; left: 3px; bottom: 3px; background-color: white; transition: .3s; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
            .bp-switch input:checked + .bp-slider { background-color: #FB7299; }
            .bp-switch input:checked + .bp-slider:before { transform: translateX(18px); }
        `;
        document.head.appendChild(style);

        const overlay = document.createElement('div');
        overlay.id = 'bp-overlay';
        const modal = document.createElement('div');
        modal.id = 'bp-modal';
        const header = document.createElement('div');
        header.id = 'bp-header';
        const title = document.createElement('h3');
        title.textContent = 'B站净化器 - 设置';
        const closeBtn = document.createElement('button');
        closeBtn.id = 'bp-close-btn';
        closeBtn.textContent = '✕';
        header.appendChild(title);
        header.appendChild(closeBtn);

        const body = document.createElement('div');
        body.id = 'bp-body';
        const cfg = getConfig();

        configStructure.forEach(group => {
            const groupTitle = document.createElement('div');
            groupTitle.className = 'bp-group-title';
            groupTitle.textContent = group.groupName;
            body.appendChild(groupTitle);

            group.items.forEach(item => {
                const row = document.createElement('div');
                row.className = 'bp-switch-row';
                const label = document.createElement('span');
                label.textContent = item.label;
                const switchContainer = document.createElement('label');
                switchContainer.className = 'bp-switch';
                const input = document.createElement('input');
                input.type = 'checkbox';
                input.checked = cfg[item.key];
                input.dataset.key = item.key;
                const slider = document.createElement('span');
                slider.className = 'bp-slider';
                switchContainer.appendChild(input);
                switchContainer.appendChild(slider);
                row.appendChild(label);
                row.appendChild(switchContainer);
                body.appendChild(row);

                input.addEventListener('change', (e) => {
                    const currentCfg = getConfig();
                    currentCfg[e.target.dataset.key] = e.target.checked;
                    saveConfig(currentCfg);
                    needReload = true;
                });
            });
        });

        modal.appendChild(header);
        modal.appendChild(body);
        overlay.appendChild(modal);
        document.body.appendChild(overlay);

        const closePanel = () => {
            document.body.removeChild(overlay);
            document.head.removeChild(style);
            isPanelOpen = false;
            if (needReload) location.reload();
        };

        closeBtn.addEventListener('click', closePanel);
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) closePanel();
        });
    }

    GM_registerMenuCommand('🧹 B站净化器设置', openSettingsPanel);


    // ================= 核心屏蔽逻辑 =================

    // 广告选择器
    const BOTTOM_BANNER_AD_SELECTOR = 'a.ad-report-inner[href*="cm.bilibili.com"], a.strip-ad[href*="cm.bilibili.com"], div.ad-report.strip-ad a[href*="cm.bilibili.com"]';
    const SIDE_AD_SELECTOR = '#slide_ad, .slide-ad-exp';
    const RIGHT_BOTTOM_AD_SELECTOR = 'div.ad-report.ad-floor-exp, div.right-bottom-banner';
    const SMALL_AD_CARD_SELECTOR = '.video-card-ad-small';
    const FEED_CONTAINER_SELECTOR = '.bili-feed4, .feed-list, .bili-video-card-list, .recommend-container, .video-page-special';
    const VIDEO_TAG_SELECTOR = '.video-tag-container';
    const ACTIVITY_BANNER_SELECTOR = '.inside-wrp';
    const HOME_CAROUSEL_AD_SELECTOR = 'div.recommended-swipe';
    const HUASHENG_BANNER_SELECTOR = 'a.upload-huasheng-banner';
    const BTN_AD_SELECTOR = 'div.btn-ad';
    // 直播间轮播广告:精确匹配包含特定数据类型的翻转容器,避免误伤
    const LIVE_BANNER_AD_SELECTOR = 'div.flip-view:has(div[data-type="liveroom_banner_show"])';

    // --- 导航栏选择器 ---
    const NAV_ANIME_SELECTOR = 'li.v-popover-wrap:has(a.default-entry[href*="anime"])';
    const NAV_LIVE_SELECTOR = 'li.v-popover-wrap:has(a.default-entry[href*="live.bilibili"])';
    const NAV_GAME_SELECTOR = 'li.v-popover-wrap:has(a.default-entry[href*="game.bilibili"])';
    const NAV_MALL_SELECTOR = 'li.v-popover-wrap:has(a.default-entry[href*="show.bilibili"])';
    const NAV_MANGA_SELECTOR = 'li.v-popover-wrap:has(a.default-entry[href*="manga.bilibili"])';
    const NAV_MATCH_SELECTOR = 'li.v-popover-wrap:has(a.default-entry[href*="match"])';
    const NAV_DOWNLOAD_SELECTOR = 'li.v-popover-wrap:has(a.download-client-trigger)';
    const NAV_VIP_SELECTOR = 'div.vip-wrap';

    // 评论区根容器(绝不处理)
    const COMMENT_ROOT_SELECTOR = '#comment-area, .comment-list-holder, .reply-list, .comment-container, .comment-list, .bili-comment';

    const HIDE_MARKER = 'data-ad-hidden';

    function isInsideCommentArea(element) {
        if (!element) return false;
        let node = element;
        while (node && node !== document.body) {
            if (node.nodeType === Node.ELEMENT_NODE && node.matches && node.matches(COMMENT_ROOT_SELECTOR)) {
                return true;
            }
            node = node.parentElement;
        }
        return false;
    }

    // 验证是否为活动横幅
    function isActivityBanner(el) {
        return el.querySelector('.hinter-msg') && el.querySelector('.inside-bg');
    }

    // 通用隐藏逻辑
    function checkAndHide(selector, configKey) {
        const cfg = getConfig();
        if (!cfg[configKey]) return;
        document.querySelectorAll(selector).forEach(el => {
            if (!isInsideCommentArea(el) && el.getAttribute(HIDE_MARKER) !== 'true') {
                el.style.display = 'none';
                el.setAttribute(HIDE_MARKER, 'true');
            }
        });
    }

    // ================= 强化:推荐流广告视频识别 =================
    function isAdVideoCard(card) {
        const adLink = card.querySelector('a[href*="cm.bilibili.com"]');
        if (adLink) return true;

        if (card.dataset && card.dataset.isAd !== undefined) return true;
        if (card.classList.contains('is-ad')) return true;

        const statsContainer = card.querySelector('.bili-video-card__stats') ||
                               card.querySelector('.bili-video-card__image .bili-video-card__mask') ||
                               card.querySelector('.feed-card-statistics');
        if (statsContainer) {
            const spans = statsContainer.querySelectorAll('span');
            for (let span of spans) {
                if (/广告|推广|AD|赞助/i.test(span.textContent.trim())) {
                    return true;
                }
            }
        }

        const imageWrap = card.querySelector('.bili-video-card__image') || card.querySelector('.feed-card-image');
        if (imageWrap) {
            const cornerTags = imageWrap.querySelectorAll('span[class*="ad"], span[class*="sponsor"], span[class*="promote"]');
            for (let tag of cornerTags) {
                if (/广告|推广|AD/i.test(tag.textContent.trim())) {
                    return true;
                }
            }
        }

        return false;
    }

    function hideVideoAdsInRecommended() {
        if (!getConfig().feedAdVideo) return;
        const containers = document.querySelectorAll(FEED_CONTAINER_SELECTOR);
        containers.forEach(container => {
            if (isInsideCommentArea(container)) return;
            const cards = container.querySelectorAll('.bili-video-card, .feed-card, .video-card');
            cards.forEach(card => {
                if (!isInsideCommentArea(card) && isAdVideoCard(card)) {
                    if (card.getAttribute(HIDE_MARKER) === 'true') return;
                    card.style.display = 'none';
                    card.setAttribute(HIDE_MARKER, 'true');
                }
            });
        });
    }

    // 统一清理入口
    function fullClean() {
        checkAndHide(BOTTOM_BANNER_AD_SELECTOR, 'bottomBanner');
        checkAndHide(SIDE_AD_SELECTOR, 'sideAd');
        checkAndHide(RIGHT_BOTTOM_AD_SELECTOR, 'rightBottomAd');
        checkAndHide(SMALL_AD_CARD_SELECTOR, 'smallAdCard');
        checkAndHide(VIDEO_TAG_SELECTOR, 'videoTag');
        checkAndHide(HOME_CAROUSEL_AD_SELECTOR, 'homeCarouselAd');
        checkAndHide(HUASHENG_BANNER_SELECTOR, 'huashengBanner');
        checkAndHide(BTN_AD_SELECTOR, 'btnAd');
        checkAndHide(LIVE_BANNER_AD_SELECTOR, 'liveBannerAd');

        // 活动横幅需特征双重验证
        if (getConfig().activityBanner) {
            document.querySelectorAll(ACTIVITY_BANNER_SELECTOR).forEach(wrp => {
                if (isActivityBanner(wrp) && !isInsideCommentArea(wrp) && wrp.getAttribute(HIDE_MARKER) !== 'true') {
                    wrp.style.display = 'none';
                    wrp.setAttribute(HIDE_MARKER, 'true');
                }
            });
        }

        hideVideoAdsInRecommended();

        // --- 清理导航栏元素 ---
        checkAndHide(NAV_ANIME_SELECTOR, 'hideAnime');
        checkAndHide(NAV_LIVE_SELECTOR, 'hideLive');
        checkAndHide(NAV_GAME_SELECTOR, 'hideGameCenter');
        checkAndHide(NAV_MALL_SELECTOR, 'hideMall');
        checkAndHide(NAV_MANGA_SELECTOR, 'hideManga');
        checkAndHide(NAV_MATCH_SELECTOR, 'hideMatch');
        checkAndHide(NAV_DOWNLOAD_SELECTOR, 'hideDownload');
        checkAndHide(NAV_VIP_SELECTOR, 'hideVip');
    }

    // 处理动态新增节点
    function processNewNode(node) {
        if (node.nodeType !== Node.ELEMENT_NODE) return;
        if (isInsideCommentArea(node)) return;

        checkAndHide(BOTTOM_BANNER_AD_SELECTOR, 'bottomBanner');
        checkAndHide(SIDE_AD_SELECTOR, 'sideAd');
        checkAndHide(RIGHT_BOTTOM_AD_SELECTOR, 'rightBottomAd');
        checkAndHide(SMALL_AD_CARD_SELECTOR, 'smallAdCard');
        checkAndHide(VIDEO_TAG_SELECTOR, 'videoTag');
        checkAndHide(HOME_CAROUSEL_AD_SELECTOR, 'homeCarouselAd');
        checkAndHide(HUASHENG_BANNER_SELECTOR, 'huashengBanner');
        checkAndHide(BTN_AD_SELECTOR, 'btnAd');
        checkAndHide(LIVE_BANNER_AD_SELECTOR, 'liveBannerAd');

        if (getConfig().activityBanner) {
            const checkActivity = (el) => {
                if (isActivityBanner(el) && !isInsideCommentArea(el) && el.getAttribute(HIDE_MARKER) !== 'true') {
                    el.style.display = 'none';
                    el.setAttribute(HIDE_MARKER, 'true');
                }
            };
            checkActivity(node);
            if (node.querySelectorAll) {
                node.querySelectorAll(ACTIVITY_BANNER_SELECTOR).forEach(wrp => checkActivity(wrp));
            }
        }

        // 广告视频卡片检查优化
        const cfg = getConfig();
        if (cfg.feedAdVideo) {
            let needScanVideo = false;
            if (node.matches && (node.matches('.bili-video-card') || node.matches('.feed-card') || node.matches(FEED_CONTAINER_SELECTOR))) {
                needScanVideo = true;
            } else if (node.querySelector && (node.querySelector('.bili-video-card') || node.querySelector('.feed-card') || node.querySelector(FEED_CONTAINER_SELECTOR))) {
                needScanVideo = true;
            }
            if (needScanVideo) {
                setTimeout(() => hideVideoAdsInRecommended(), 80);
            }
        }

        // --- 动态节点导航栏检查 ---
        checkAndHide(NAV_ANIME_SELECTOR, 'hideAnime');
        checkAndHide(NAV_LIVE_SELECTOR, 'hideLive');
        checkAndHide(NAV_GAME_SELECTOR, 'hideGameCenter');
        checkAndHide(NAV_MALL_SELECTOR, 'hideMall');
        checkAndHide(NAV_MANGA_SELECTOR, 'hideManga');
        checkAndHide(NAV_MATCH_SELECTOR, 'hideMatch');
        checkAndHide(NAV_DOWNLOAD_SELECTOR, 'hideDownload');
        checkAndHide(NAV_VIP_SELECTOR, 'hideVip');
    }

    // MutationObserver 监听页面变化
    const observer = new MutationObserver(mutations => {
        let hasAddedNodes = false;
        for (const mutation of mutations) {
            if (mutation.type === 'childList' && mutation.addedNodes.length) {
                mutation.addedNodes.forEach(node => processNewNode(node));
                hasAddedNodes = true;
            }
        }
        if (hasAddedNodes) {
            setTimeout(() => {
                fullClean();
            }, 150);
        }
    });

    if (document.body) {
        observer.observe(document.body, { childList: true, subtree: true });
    } else {
        window.addEventListener('DOMContentLoaded', () => {
            observer.observe(document.body, { childList: true, subtree: true });
        });
    }

    // SPA 路由变化辅助
    let lastUrl = location.href;
    const urlObserver = new MutationObserver(() => {
        if (location.href !== lastUrl) {
            lastUrl = location.href;
            setTimeout(fullClean, 300);
        }
    });
    urlObserver.observe(document, { subtree: true, childList: true });

    // 启动清理
    fullClean();

})();
哔哩哔哩广告全面屏蔽 & 导航精简-3.2.user.js.zip (10.16 KB, 下载次数: 0, 售价: 1 CB吾爱币)

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-8-28 11:39

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表