您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
隐藏B站动态瀑布流中的广告、评论区广告、充电内容以及美化首页
// ==UserScript== // @name Bilibili-隐藏充电和广告 // @namespace https://greasyfork.org/scripts/511437/ // @description 隐藏B站动态瀑布流中的广告、评论区广告、充电内容以及美化首页 // @version 1.26 // @author chemhunter // @match *://t.bilibili.com/* // @match *://space.bilibili.com/* // @match *://www.bilibili.com/* // @grant GM_registerMenuCommand // @icon https://i0.hdslb.com/bfs/static/jinkela/long/images/favicon.ico // @run-at document-end // @license GPL-3.0 License // ==/UserScript== (function() { 'use strict'; const keywordList = [ '拼多多', '淘宝', '京东', '天猫', '手淘', '旗舰店','运费','返现', '甲方', '催更', '双11', '双12','双十一','618','回购', //购物平台 '特价','下单','礼包','补贴','领券','优惠','折扣','福利','评论区', '置顶链接','蓝链','退款','保价','限时','免费','专属', //商家话术 '品牌方', '他们家','赞助', '溪木源', '海力生', '萌牙家', '妙界', '神气小鹿', 'DAWEI', '温眠', '友望', '转转','礼盒', //品牌商家 '冰被','工学椅','润眼','护肝','护颈','颈椎','护眼','护枕','肩颈‘,’按摩','冲牙','牙刷','肯德基','洗地机','鱼油','氨糖', //产品功能 '产品','成分','配比','配方','精粹','精华', '美白','牙渍','菌斑','久坐','疲劳','白茶','好价','降价','保养','控油', '质感','科技感','口碑','热销','自研','养护','流量','送礼','放心冲','大额', ]; const blockedLinks = [ 'taobao.com','tb.cn', 'jd.com', 'pinduoduo.com', 'mall.bilibili.com', 'gaoneng.bilibili.com', 'yangkeduo.com', 'zhuanzhuan.com', 'goofish.com', 'firegz.com', '52haoka.com','aiyo-aiyo.com', 'bilibili.com/cheese/' ]; function log(...args) { console.log('[B站隐藏充电和广告] ', ...args); } function hideItem(item) { item.style.display = 'none'; } function showMessage(msg) { messageDiv.textContent = msg; messageDiv.style.display = 'block'; setTimeout(() => { messageDiv.style.display = 'none'; }, 3000); } // 检查评论区广告 function checkCommentTopAds() { const commentAds = document.querySelectorAll('.dynamic-card-comment .comment-list.has-limit .list-item.reply-wrap.is-top'); commentAds.forEach(comment => { const links = comment.querySelectorAll('a'); links.forEach(link => { const href = link.getAttribute('href'); if (href && blockedLinks.some(blocked => href.includes(blocked))) { hideItem(comment); return 1; } }); }); return 0; } let hiddenAdCount = 0; function checkCommentsForAds() { const commentsContainer = document.querySelector('#commentapp > bili-comments'); if (commentsContainer && commentsContainer.shadowRoot) { const headerElement = commentsContainer.shadowRoot.querySelector("#header > bili-comments-header-renderer"); if (headerElement && headerElement.shadowRoot) { const noticeElement = headerElement.shadowRoot.querySelector("#notice > bili-comments-notice"); if (noticeElement && noticeElement.shadowRoot) { const closeElement = noticeElement.shadowRoot.querySelector("#close"); if (closeElement) { log("找到评论区横条,自动点击关闭按钮"); closeElement.click(); } } const thread = commentsContainer.shadowRoot.querySelector('bili-comment-thread-renderer'); if (thread && window.getComputedStyle(thread).display !== 'none' && thread.shadowRoot) { const commentRenderer = thread.shadowRoot.querySelector('#comment'); if (commentRenderer && commentRenderer.shadowRoot) { const richText = commentRenderer.shadowRoot.querySelector('#content > bili-rich-text'); if (richText && richText.shadowRoot) { const contentsElement = richText.shadowRoot.querySelector('#contents'); if (contentsElement) { let foundAd = false; const contentText = contentsElement.textContent; if (blockedKeywords.some(keyword => contentText.includes(keyword))) { foundAd = true; } const links = contentsElement.querySelectorAll('a'); links.forEach(link => { const href = link.getAttribute('href'); if (href && blockedLinks.some(blocked => href.includes(blocked))) { foundAd = true; } }); if (foundAd) { log('发现评论区广告'); hideItem(thread); hiddenAdCount++; observer.disconnect(); let message = `隐藏广告 x ${hiddenAdCount}`; showMessage(message); return true; } } } } } } return false; } } function checkForContentToHide() { let hiddenChargeCount = 0; let hiddenAdCount = 0; if (window.location.hostname === 't.bilibili.com' || window.location.hostname === 'space.bilibili.com') { if (window.location.hostname === 't.bilibili.com') { hiddenAdCount += checkCommentTopAds(); } const items = document.querySelectorAll('.bili-dyn-list__item'); items.forEach(item => { const titleElement = item.querySelector('.bili-dyn-title'); if (titleElement && whiteList.includes(titleElement.textContent.trim())) { return; } const ask = item.querySelector('.dyn-icon-badge__renderimg.bili-dyn-item__iconbadge'); const blockedmask = item.querySelector('.dyn-blocked-mask'); const badge = item.querySelector('.bili-dyn-card-video__badge'); const lotteryTitle = item.querySelector('.dyn-upower-lottery__title'); const contentDiv = item.querySelector('.bili-dyn-content'); const goods = item.querySelector('dyn-goods'); const goods2 = item.querySelector('bili-dyn-card-goods'); const spans = item.querySelectorAll('span'); if (window.getComputedStyle(item).display !== 'none') { if (goods || goods2) { hideItem(item); hiddenAdCount++; } else if (blockedmask || ask || (badge && badge.textContent.includes('专属') || Array.from(spans).some(span => span.textContent.includes('专属')) || (lotteryTitle && lotteryTitle.textContent.includes('专属'))) ) { hideItem(item); hiddenChargeCount++; } else if (contentDiv) { const contentText = contentDiv.textContent; if (blockedKeywords.some(keyword => contentText.includes(keyword))) { hideItem(item); hiddenAdCount++; } } } if (window.getComputedStyle(item).display !== 'none') { spans.forEach(span => { const dataUrl = span.getAttribute('data-url'); if (dataUrl && blockedLinks.some(blocked => dataUrl.includes(blocked))) { hideItem(item); hiddenAdCount++; } }); } }); } if (window.location.hostname === 'www.bilibili.com' && !window.location.pathname.startsWith('/video/')) { // 隐藏推广的 feed 卡片 const floorCards = document.querySelectorAll('.floor-single-card'); floorCards.forEach(card => { if (window.getComputedStyle(card).display !== 'none'){ hideItem(card); } }); // 隐藏没有视频内容的 feed 卡片 const feedCards = document.querySelectorAll('.feed-card'); feedCards.forEach(card => { const hasVideoWrap = card.querySelector('.bili-video-card__wrap'); if (!hasVideoWrap) { card.style.display = 'none'; } }); //隐藏首页大屏 const targetElement = document.querySelector('.recommended-swipe'); if (targetElement && window.getComputedStyle(targetElement).display !== 'none') { hideItem(targetElement); } } if (window.location.pathname.startsWith('/video/')) { if (!checkCommentsForAds()) { setTimeout(() => { checkCommentsForAds(); }, 2000); } const targetElement = document.querySelector('.bili-mini-mask'); const popElement = document.querySelector('.v-popover'); if (targetElement && window.getComputedStyle(targetElement).display !== 'none') { log('隐藏登录'); hideItem(targetElement); } } let message = ''; if (hiddenChargeCount > 0) { message += `隐藏充电 x ${hiddenChargeCount} `; } if (hiddenAdCount > 0) { message += `隐藏广告 x ${hiddenAdCount} `; } if (message) { showMessage(message.trim()); } } // 元素是否可见 function isVisible(el) { return el && el.offsetParent !== null; } //上方动态按钮触发弹窗 function watchDynamicAllPanel() { const observer = new MutationObserver(mutations => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeType === 1) { const panel = node.querySelector('.dynamic-all'); if (panel) { //log('✅ .dynamic-all 已插入,等待显示...'); const checkVisible = setInterval(() => { if (isVisible(panel)) { //log('✅ .dynamic-all 已显示,执行广告过滤'); filterDynamicPanelLinks(panel); } else { clearInterval(checkVisible); } }, 300); } } } } }); observer.observe(document.body, { childList: true, subtree: true }); log('监听 document.body'); } // 根据动态 title 和“专栏”标签判断是否广告,隐藏广告 function filterDynamicPanelLinks() { const panel = document.querySelector('.dynamic-all'); if (!panel) return; const links = panel.querySelectorAll( 'a[data-mod="top_right_bar_window_dynamic"][data-idx="content"][title]' ); let hiddenCount = 0; links.forEach(link => { if (isVisible(link)) { const title = link.getAttribute('title') || ''; const tagSpan = link.querySelector( '.dynamic-info-content > .all-in-one-article-title > .article-tag' ); const isZhuanlan = tagSpan && tagSpan.textContent.trim() === '专栏'; if (!isZhuanlan) return; if (title.includes("!") || blockedKeywords.some(kw => title.includes(kw))) { let author = '未知'; const avatar = link.querySelector('.header-dynamic-avatar[title]'); if (avatar) { author = avatar.getAttribute('title') || ''; } if (!author) { const usernameEl = link.querySelector('.user-name a[title]'); if (usernameEl) { author = usernameEl.getAttribute('title') || usernameEl.textContent.trim(); } } log(`🚫「${author}」广告:${title}`); link.style.display = 'none'; hiddenCount++; } } }); if (hiddenCount > 0) { let message = `隐藏动态广告 x ${hiddenCount} `; showMessage(message.trim()); log(`✅ 已隐藏 ${hiddenCount} 条动态广告链接`); } } function debounce(func, wait) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); }; } function initObserver() { const observer = new MutationObserver(debounce(checkForContentToHide, 250)); observer.observe(document.body,{ childList: true, subtree: true, attributes: true, attributeFilter: ['class'] }); return observer; } function restartObserver() { log('页面内容更新,重新启动observer'); if (window.observer) { window.observer.disconnect(); } const observer = initObserver(); window.observer = observer; } // 监听 commentapp 元素的变化 function initCommentAppObserver() { const commentAppElement = document.querySelector('#commentapp'); if (commentAppElement) { const commentAppObserver = new MutationObserver(restartObserver); commentAppObserver.observe(commentAppElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['class']}); log('启动commentapp 元素observer'); } } // 初始化白名单 let whiteList = JSON.parse(localStorage.getItem('whiteList')) || []; // 添加到白名单 function addToWhiteList(upId) { if (!whiteList.includes(upId)) { whiteList.push(upId); localStorage.setItem('whiteList', JSON.stringify(whiteList)); //alert(`已将 ${upId} 添加到白名单`); updateWhiteListDisplay(); // 更新显示 } else { alert(`${upId} 已在白名单中`); } } // 从白名单中移除 function removeFromWhiteList(upId) { const index = whiteList.indexOf(upId); if (index !== -1) { whiteList.splice(index, 1); localStorage.setItem('whiteList', JSON.stringify(whiteList)); //alert(`已将 ${upId} 从白名单中移除`); updateWhiteListDisplay(); // 更新显示 } else { alert(`${upId} 不在白名单中`); } } // 检查是否在白名单中 function isInWhiteList(upId) { return whiteList.includes(upId); } // 更新白名单显示 function updateWhiteListDisplay() { const listDisplay = document.getElementById('whiteListDisplay'); if (listDisplay) { listDisplay.textContent = whiteList.join(', ') || '白名单为空'; } } // 显示白名单管理菜单 function WhiteListMenu() { const adContainer = document.createElement('div'); adContainer.id = 'kimiAdContainer'; adContainer.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 500px; padding: 20px; background: #fff; border: 1px solid #ccc; border-radius: 10px; z-index: 10000; font-size: 16px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); `; const Title = document.createElement('h4'); Title.textContent = `手动管理白名单`; Title.style.cssText = 'text-align: center; margin-bottom: 20px;'; adContainer.appendChild(Title); // 添加UP部分 const addUpRow = document.createElement('div'); addUpRow.style.cssText = 'display: flex; align-items: center; margin-bottom: 10px;'; const addUpLabel = document.createElement('label'); addUpLabel.textContent = '添加UP的ID:'; addUpLabel.style.marginRight = '10px'; addUpRow.appendChild(addUpLabel); const addUpInput = document.createElement('input'); addUpInput.type = 'text'; addUpInput.id = 'kimiaddUp'; addUpInput.placeholder = '请输入UP的ID'; addUpInput.style.flex = '0.7'; addUpRow.appendChild(addUpInput); const saveButton = document.createElement('button'); saveButton.textContent = '增加'; saveButton.style.marginLeft = '20px'; saveButton.style.padding = '0px 20px'; saveButton.style.minWidth = '80px'; saveButton.addEventListener('click', () => { const upId = addUpInput.value.trim(); if (upId) { addToWhiteList(upId); addUpInput.value = ''; // 清空输入框 } }); addUpRow.appendChild(saveButton); adContainer.appendChild(addUpRow); // 删除UP部分 const removeUpRow = document.createElement('div'); removeUpRow.style.cssText = 'display: flex; align-items: center; margin-bottom: 10px;'; const removeUpLabel = document.createElement('label'); removeUpLabel.textContent = '删除UP的ID:'; removeUpLabel.style.marginRight = '10px'; removeUpRow.appendChild(removeUpLabel); const removeUpInput = document.createElement('input'); removeUpInput.type = 'text'; removeUpInput.id = 'kimiremoveUp'; removeUpInput.placeholder = '请输入UP的ID'; removeUpInput.style.flex = '0.7'; removeUpRow.appendChild(removeUpInput); const deleteButton = document.createElement('button'); deleteButton.textContent = '删除'; deleteButton.style.marginLeft = '20px'; deleteButton.style.padding = '0px 20px'; deleteButton.style.minWidth = '80px'; deleteButton.addEventListener('click', () => { const upId = removeUpInput.value.trim(); if (upId) { removeFromWhiteList(upId); removeUpInput.value = ''; // 清空输入框 } }); removeUpRow.appendChild(deleteButton); adContainer.appendChild(removeUpRow); // 白名单列表显示区域 const listDiv = document.createElement('div'); listDiv.id = 'whiteListDisplay'; listDiv.style.cssText = ` text-align: center; color: #555; margin: 20px 0; padding: 10px; border: 1px dashed #ccc; border-radius: 5px; font-size: 14px; word-break: break-word; max-height: 150px; overflow-y: auto; `; listDiv.textContent = whiteList.join(', ') || '白名单为空'; adContainer.appendChild(listDiv); // 完成按钮 const finishButton = document.createElement('button'); finishButton.textContent = '完成'; finishButton.style.cssText = 'display: block; margin: 0 auto; padding: 5px 20px;'; finishButton.addEventListener('click', () => { document.body.removeChild(adContainer); }); adContainer.appendChild(finishButton); document.body.appendChild(adContainer); } // 注册菜单命令 GM_registerMenuCommand("UP白名单", WhiteListMenu); const messageDiv = document.createElement('div'); Object.assign(messageDiv.style, { position: 'fixed', top: '10px', right: '10px', padding: '10px', backgroundColor: 'rgba(0, 0, 0, 0.7)', color: 'white', borderRadius: '5px', zIndex: '9999', display: 'none' }); document.body.appendChild(messageDiv); log('脚本加载,初始化'); const observer = initObserver(); window.observer = observer; initCommentAppObserver(); watchDynamicAllPanel(); })();