您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
移除B站首页推荐中的所有推广视频广告,包括小火箭🚀,漫画,纪录片等,以及正统广告。使用Pixiv推荐图片替换广告内容。需要提前登陆过pixiv账号,不需要Cookies或者账号token。
当前为
// ==UserScript== // @name B站广告替换为Pixiv推荐图片 // @name:en Bilibili Ad Replacement with Pixiv Recommended Images // @namespace http://tampermonkey.net/ // @version 1.4.1 // @description 移除B站首页推荐中的所有推广视频广告,包括小火箭🚀,漫画,纪录片等,以及正统广告。使用Pixiv推荐图片替换广告内容。需要提前登陆过pixiv账号,不需要Cookies或者账号token。 // @description:en Remove promotional video ads from Bilibili's homepage recommendations, including small rocket 🚀 ads and regular ads. Use Pixiv recommended images to replace the ads. A Pixiv account must be logged in beforehand, but no cookies or account tokens are required. // @author RecycleBee // @match *://www.bilibili.com/* // @match *://www.pixiv.net/en/* // @grant GM_openInTab // @grant GM_addValueChangeListener // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== (function() { 'use strict'; const currentUrl = window.location.href; // === 处理 Pixiv 页面 === if (currentUrl.includes("pixiv.net/en/")) { console.log("少女祈祷中..."); function waitForElements(selector, callback, timeout = 10000) { const startTime = Date.now(); const checkInterval = 500; function check() { let elements = document.querySelectorAll(selector); if (elements.length > 0) { callback(elements); } else if (Date.now() - startTime < timeout) { setTimeout(check, checkInterval); } else { console.warn("超时,未找到目标元素"); } } check(); } function closePage() { window.close(); } async function fetchIllustDetails(pixivID) { const apiUrl = `https://www.pixiv.net/ajax/illust/${pixivID}`; try { const response = await fetch(apiUrl); const data = await response.json(); if (data.body && data.body.urls) { let imgUrl = data.body.urls.original; imgUrl = imgUrl.replace(/\\/g, ""); const dateMatch = imgUrl.match(/\/(\d{4})\/(\d{2})\/(\d{2})\/(\d{2})\/(\d{2})\/(\d{2})\/(\d+)/); if (dateMatch) { const [_, year, month, day, hour, minute, second, id] = dateMatch; const newImgUrl = `https://i.pixiv.cat/c/360x360_70/img-master/img/${year}/${month}/${day}/${hour}/${minute}/${second}/${id}_p0_square1200.jpg`; const formattedDate = `${year}-${month}-${day}`; const illustTitle = data.body.title; const authorId = data.body.tags.authorId; const userUrl = `https://www.pixiv.net/en/users/${authorId}`; const artworkUrl = `https://www.pixiv.net/en/artworks/${pixivID}`; const username = data.body.userName; console.log(`作品ID ${pixivID} 缩略URL:${newImgUrl}`); return { imgUrl: newImgUrl, illustTitle, artworkUrl, userUrl, date: formattedDate, username, }; } else { console.warn(`无法提取${pixivID}`); return null; } } } catch (error) { console.error("获取信息时报错:", error); return null; } } async function fetchAllPixivUrls(uniquePixivIDs) { let imgUrls = []; let additionalData = []; for (const pixivID of uniquePixivIDs) { const result = await fetchIllustDetails(pixivID); if (result) { imgUrls.push(result.imgUrl); // 添加图片URL additionalData.push({ title: result.illustTitle, artworkUrl: result.artworkUrl, userUrl: result.userUrl, date: result.date, username: result.username, }); } } GM_setValue("pixivImgUrls", imgUrls); GM_setValue("pixivAdditionalData", additionalData); return { imgUrls, additionalData }; } if (GM_getValue("isFetchingPixiv", false)) { console.log("少女不用祈祷..."); return; } waitForElements("div.gtm-toppage-thumbnail-illustration-recommend-works-zone", async function(divs) { let pixivIDs = new Set(); // 去重 divs.forEach(div => { div.querySelectorAll('a[href^="/en/artworks/"]').forEach(anchor => { let href = anchor.getAttribute("href"); let match = href.match(/^\/en\/artworks\/(\d+)/); if (match) { pixivIDs.add(match[1]); } }); }); let uniquePixivIDs = Array.from(pixivIDs); // 转为数组 await fetchAllPixivUrls(uniquePixivIDs); GM_setValue("pixivFetched", true); closePage(); }); return; } // === 处理 Bilibili 页面 === // 预加载图片 function preloadImages(imageUrls) { imageUrls.forEach(url => { if (!preloadedImages.some(img => img.src === url)) { let img = new Image(); img.src = url; preloadedImages.push(img); } }); } function removeAds() { // 1.处理未替换的广告 document.querySelectorAll('.bili-video-card.is-rcmd').forEach(card => { if (!card.classList.contains('enable-no-interest')) { let imageLink = card.querySelector('.bili-video-card__image--link'); if (imageLink) { // 获取父元素的宽度 let parentWidth = card.offsetWidth; let parentHeight = parentWidth * (9 / 16); let placeholder = document.createElement("div"); placeholder.style.cssText = ` position: relative; width: 100%; height: 0; padding-top: 56.25%; background: #f4f4f4; border-radius: 8px; border: 1px dashed #ccc; margin: auto; `; let textContainer = document.createElement("div"); textContainer.style.cssText = ` position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #888; font-size: 14px; font-weight: bold; text-align: center; width: 100%; `; textContainer.innerText = "🚫 广告已屏蔽"; placeholder.appendChild(textContainer); imageLink.replaceWith(placeholder); // 清空文字内容,但保留元素结构,不知道为什么一定得要有字符在innerText,空格还不行。 let placeholderText = "\u200B"; let titleElement = card.querySelector('.bili-video-card__info--tit'); if (titleElement) { let link = titleElement.querySelector('a'); if (link) { link.innerText = placeholderText; } } let authorElement = card.querySelector('.bili-video-card__info--author'); if (authorElement) authorElement.innerText = placeholderText; let dateElement = card.querySelector('.bili-video-card__info--date'); if (dateElement) dateElement.innerText = placeholderText; let creativeAd = card.querySelector('.vui_icon.bili-video-card__info--creative-ad'); if (creativeAd) creativeAd.remove(); let adInfo = card.querySelector('.bili-video-card__info--ad'); if (adInfo) adInfo.remove(); isPixivImageLoaded = false; processAdsOrPlaceholders(placeholder); } } }); // 处理已经替换成占位符的广告封面 document.querySelectorAll('div').forEach(placeholder => { if (placeholder.innerText === "🚫 广告已屏蔽") { processAdsOrPlaceholders(placeholder); } }); } function processAdsOrPlaceholders(element) { let pixivImgUrls = GM_getValue("pixivImgUrls", []); let additionalData = GM_getValue("pixivAdditionalData", []); if (pixivImgUrls.length>0) { let imgUrl = pixivImgUrls.shift(); let { artworkUrl, title, date, username, userUrl} = additionalData.shift(); if (imgUrl) { preloadImages(pixivImgUrls); // 预加载剩余图片 let img = document.createElement("img"); img.src = imgUrl; img.alt = "Pixiv 图片"; img.style.cssText = ` position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 8px; `; //包裹图片 let link = document.createElement("a"); link.href = artworkUrl; link.target = "_blank"; link.style.display = "block"; link.appendChild(img); //图片容器 let imgContainer = document.createElement("div"); imgContainer.style.cssText = ` position: relative; width: 100%; height: 0; padding-top: 56.25%; background: #f4f4f4; border-radius: 8px; overflow: hidden; `; imgContainer.appendChild(link); element.removeAttribute('style'); element.innerHTML = ""; // 清空原内容 element.appendChild(imgContainer); // 更新其他信息 let titleContainer = element.closest('.bili-video-card').querySelector('.bili-video-card__info--tit'); if (titleContainer) { titleContainer.title = title; let titleElement = titleContainer.querySelector('a'); if (titleElement) { titleElement.innerText = title; titleElement.href = artworkUrl; titleElement.title = title; } } let ownerElement = element.closest('.bili-video-card').querySelector('.bili-video-card__info--owner'); if (ownerElement) ownerElement.href = userUrl; let authorElement = element.closest('.bili-video-card').querySelector('.bili-video-card__info--author'); if (authorElement) { authorElement.innerText = username; authorElement.title = username; } let dateElement = element.closest('.bili-video-card').querySelector('.bili-video-card__info--date'); if (dateElement) dateElement.innerText = "· " + date; // 删除广告标识 element.closest('.bili-video-card').querySelectorAll('.vui_icon.bili-video-card__info--creative-ad, .bili-video-card__info--ad') .forEach(el => el.remove()); // 标记 Pixiv 图片已加载 isPixivImageLoaded = true; // 更新存储 GM_setValue("pixivImgUrls", pixivImgUrls); console.log("ID剩余:"+pixivImgUrls.length); GM_setValue("pixivAdditionalData", additionalData); } if (pixivImgUrls.length <= minThreshold && !isFetchingPixiv) { console.log(`图片少于 ${minThreshold} 张(当前 ${pixivImgUrls.length} 张),重新抓取...`); isFetchingPixiv = true; GM_setValue("pixivFetched", false); GM_openInTab("https://www.pixiv.net/en/", { active: false, insert: true, setParent: true }); } } } function removeSpecificElements() { // 1.删除所有纪录片、漫画等 document.querySelectorAll('div[data-v-128321c6]').forEach(element => { element.remove(); }); // 2.删除所有瀑布流的广告 document.querySelectorAll('div[data-v-3581b8d4]').forEach(element => { if (!element.closest('.feed-card') && element.classList.contains('bili-video-card') && element.classList.contains('is-rcmd') && element.classList.length === 2) { element.remove(); } }); } console.log("Bilibili 运行,检测是否需要抓取 Pixiv 图片..."); let isFetchingPixiv = false; let pixivImgUrls = GM_getValue("pixivImgUrls", []); // 检查是否有 URLs let minThreshold = 3; // 设定最少剩余图片数,低于这个值就触发抓取 if (pixivImgUrls.length <= minThreshold && !isFetchingPixiv) { console.log(`图片少于 ${minThreshold} 张,重新抓取...`); let isFetchingPixiv = true; let tab = GM_openInTab("https://www.pixiv.net/en/", { active: false, insert: true, setParent: true }); } // 让火焰净化一切!!! let preloadedImages = []; removeSpecificElements(); GM_addValueChangeListener("pixivFetched", (name, oldValue, newValue, remote) => { if (newValue === true) { console.log("Pixiv 图片已抓取,等待 DOM 加载后更新广告..."); isPixivImageLoaded = false; isFetchingPixiv = false; let observer = new MutationObserver(() => { if (document.querySelector('.bili-video-card')) { removeAds(); observer.disconnect(); // 只执行一次 } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => { if (document.body) { removeAds(); } else { console.warn("DOM未加载"); setTimeout(removeAds, 500); } }, 500); } }); let isPixivImageLoaded = false; removeAds(); // 监听 DOM let observer = new MutationObserver(() => { removeSpecificElements(); removeAds(); }); observer.observe(document.body, { childList: true, subtree: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址