您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
remove all ads from bilibili.com
// ==UserScript== // @name dgj's bilibili ads guard // @namespace http://tampermonkey.net/ // @version 2024-06-18 // @description remove all ads from bilibili.com // @author noobdawn // @match https://www.bilibili.com/ // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== (function() { 'use strict'; var blockData = localStorage.getItem("dgjBlockData"); //if (blockData === null) { blockData = { "up_name": "", // up主的名字 "up_uid": "", // up主的UID "video_keyword": // sb游戏 "剑网3,原神,崩坏,星穹铁道,星铁,绝区,未定事件簿,米哈游,仙家军,明日方舟,鹰角,海猫,鸣潮,战双帕弥什,库洛,少前,少女前线,面包房少女,散爆,羽中,无期迷途,叠纸,奇迹暖暖,无限暖暖,恋与深空,恋与制作人,百面千相,姚润昊,深空之眼,来古弥新,物华弥新,新月同行,归龙潮,破晓序列,卡拉彼丘,碧蓝档案,蔚蓝档案,雀魂,以闪亮之名,光与夜之恋,尘白禁区", // 视频的关键词 "video_label": // sb游戏 "鸣潮,鸣潮公测二创,鸣潮公测创作者激励计划,新三国,火影忍者手游,地下城与勇士,dnf,dnfpk,300英雄,MOBA,三百英雄,剑网3,星穹铁道2.2波提欧,暴雪,原神,崩坏,崩坏学园2,崩坏3,崩坏星穹铁道,星穹铁道,绝区零,绝区0,未定事件簿,米哈游,仙家军,明日方舟,鹰角,鹰角网络,海猫,鸣潮,战双帕弥什,库洛,少前,少前2,少女前线,少女前线2,面包房少女,散爆,羽中,叠纸游戏,奇迹暖暖,无限暖暖,恋与深空,恋与制作人,百面千相,姚润昊,深空之眼,来古弥新,物华弥新,新月同行,归龙潮,望月,破晓序列,卡拉彼丘,碧蓝档案,蔚蓝档案,雀魂,以闪亮之名,光与夜之恋,尘白禁区" + // 没营养的东西 "助眠,生活,情感,日常,校园,娱乐,记录,舞蹈,Vtuber,hololive,免单挑战,探店,美食,时尚,穿搭" // 视频的标签 }; blockData.up_name = blockData.up_name.split(","); blockData.video_keyword = blockData.video_keyword.split(","); blockData.video_label = blockData.video_label.split(","); blockData.up_uid = blockData.up_uid.split(","); localStorage.setItem("dgjBlockData", JSON.stringify(blockData)); } const DEBUG = true; function removeAds(node, msg) { if (DEBUG) { // 删除所有子元素 while (node.firstChild) { node.removeChild(node.firstChild); } // 添加一个文本节点 node.appendChild(document.createTextNode(msg)); } else node.remove(); } // 从URL中获取UID function GetUidFromUrl(url) { var index = url.indexOf("space.bilibili.com/"); if (index === -1) return -1; // 将剩下的所有字符转换为字符串 var uid = url.substring(index + 19); return parseInt(uid); } // 根据UP主屏蔽视频 function BlockVideoByUp(node) { // 向下查找,找到class为"bili-video-card__info--owner"的a,这就是UP主的链接 var owner = node.getElementsByClassName("bili-video-card__info--owner"); if (owner.length > 0) { var uid = GetUidFromUrl(owner[0].href); if (uid === -1) return true; // 如果uid在blockData的up_uid数组中,就删除这个视频 if (blockData.up_uid.indexOf(uid) !== -1) { removeAds(node, "触发UP主:" + uid); return true; } owner = node.getElementsByClassName("bili-video-card__info--author"); if (owner.length > 0) { var name = owner[0].innerText; // 如果name在blockData的up_name数组中,就删除这个视频 if (blockData.up_name.indexOf(name) !== -1) { removeAds(node, "触发UP主:" + name); return true; } } return false; } return true; } // 根据视频屏蔽视频 function BlockVideoByVideo(node) { var link = node.getElementsByClassName("bili-video-card__info--tit"); if (link.length > 0) { console.log(link[0].title); var title = link[0].title; for (var j = 0; j < blockData.video_keyword.length; j++){ if (title.includes(blockData.video_keyword[j])) { removeAds(node, "触发关键字:" + blockData.video_keyword[j]); return; } } } // 向下查找,找到class为"bili-video-card__image--link"的a,这就是视频的链接 link = node.getElementsByClassName("bili-video-card__image--link"); if (link.length > 0) { var url = link[0].href; // 打开视频链接,获取视频的关键词和标签 GM_xmlhttpRequest({ method: "GET", url: url, onload: function(response) { var data = response.responseText; // 找到<meta data-vue-meta="true" itemprop="keywords" name="keywords" content=" let start_string = "<meta data-vue-meta=\"true\" itemprop=\"keywords\" name=\"keywords\" content=\""; let end_string = "\"><meta"; var index = data.indexOf(start_string); if (index !== -1) { var keywords = data.substring(index + start_string.length, data.indexOf(end_string, index)); var keywordArray = keywords.split(","); // 抛弃第一个元素 keywordArray.shift(); console.log(keywordArray); // 如果labels数组中有一个元素在blockData的video_label数组中,就删除这个视频 for (i = 0; i < keywordArray.length; i++) { if (blockData.video_label.indexOf(keywordArray[i]) !== -1) { removeAds(node, "触发标签:" + keywordArray[i]); return; } } } } }); } } // 每次页面元素变化时,都会触发此函数 var observer = new MutationObserver(function(mutations) { // 遍历所有变化 mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { if (node instanceof HTMLDivElement) { // 为菜单新增一个按钮 if (node.className === "bili-video-card__info--no-interest-panel") { // 创建一个新的选项,class为"bili-video-card__info--no-interest-panel--item",innerText为"屏蔽此UP主" var item = document.createElement("div"); item.className = "bili-video-card__info--no-interest-panel--item"; item.innerText = "屏蔽此UP主"; // 将新的选项插入到菜单中 node.appendChild(item); // 监听点击事件 item.addEventListener("click", function() { // todo }); } // 如果新增的节点的class为"floor-single-card",这部分一般是直播间、番剧、国创、课堂、综艺推荐卡片,干掉 if (node.className === "floor-single-card") { removeAds(node, "Ban原因:推送"); return; } // 如果新增的节点的class为"bili-video-card is-rcmd",这部分一般是不能点不感兴趣的卡片,直接干掉 if (node.className === "bili-video-card is-rcmd") { removeAds(node, "Ban原因:广告"); return; } if (node.className === "bili-video-card is-rcmd enable-no-interest") { node.style.marginTop = '22px'; } if (BlockVideoByUp(node) !== true) BlockVideoByVideo(node); } }); }); }); // 监听整个文档 observer.observe(document, { childList: true, subtree: true }); // 移除滚动播放广告 // 找到所有class为"recommended-swipe grid-anchor"的div,这就是左上角的广告滚动页 var ads = document.getElementsByClassName("recommended-swipe grid-anchor"); for (var i = 0; i < ads.length; i++) { removeAds(ads[i], "Ban原因:广告滚动页"); } // 找到所有首页的广告 // 找到所有class为"bili-video-card is-rcmd"的div ads = document.getElementsByClassName("bili-video-card is-rcmd"); for (i = 0; i < ads.length; i++) { if (ads[i].className === "bili-video-card is-rcmd") { if (ads[i].parentNode.className === "feed-card") removeAds(ads[i].parentNode, "Ban原因:广告"); else removeAds(ads[i], "Ban原因:广告"); } } ads = document.getElementsByClassName("feed-card"); for (i = 0; i < ads.length; i++) { // 将样式中的margin-top设为40像素 ads[i].style.marginTop = '22px'; if (BlockVideoByUp(ads[i]) !== true) BlockVideoByVideo(ads[i]); } })();