// ==UserScript== // @name 2025年智能YouTube全站广告拦截器 // @version 2.3 // @description 精准广告拦截,支持多平台保护 // @icon https://www.youtube.com/favicon.ico // @author little fool // @match *://*/* // @grant GM_addStyle // @grant unsafeWindow // @run-at document-start // @namespace https://yournamespace.com // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; GM_addStyle(` .adblocker-status-icon { position: fixed; bottom: 20px; right: 20px; width: 40px; height: 40px; background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij48cGF0aCBkPSJNMjEuNTggNy4xOWMtLjIzLS44Ni0uOTQtMS41MS0xLjgxLTEuNzNDMTguMjQ1IDAgNSAwIDUgMHMtMTguMjQgMC0xOS43Ny40NmMtLjg3LjIyLTEuNTguODctMS44IDEuNzNDMCA4LjcxIDAgMTIgMCAxMnMwIDMuMjkuMDMgNC44MWMuMjIuODYuOTMgMS41MSAxLjggMS43MyAxLjUzLjQ4IDE5Ljc3LjQ4IDE5Ljc3LjQ4czE4LjI0IDAgMTkuNzctLjQ2Yy44Ny0uMjIgMS41OC0uODcgMS44LTEuNzMuMDMtMS41Mi4wMy0zLjI5LjAzLTQuODFzLS4wMS0zLjI5LS4wMy00Ljgxek0xMCAxNWw4LjgtNUwxMCA1djEweiIgZmlsbD0iI2ZmMDAwMCIvPjwvc3ZnPg==') no-repeat center/cover; cursor: pointer; z-index: 99999; opacity: 0.8; transition: all 0.3s; border-radius: 50%; box-shadow: 0 2px 5px rgba(0,0,0,0.3); } .adblocker-tooltip { position: fixed; bottom: 70px; right: 20px; background: rgba(0,0,0,0.9); color: #fff; padding: 10px 15px; border-radius: 6px; font-size: 13px; display: none; white-space: nowrap; backdrop-filter: blur(2px); } `); // 修正核心配置 const SecurityConfig = { protectedDomains: { 'youtube.com': { icon: true, selectors: [ 'ytd-display-ad-renderer', '#player-ads', '.ytp-ad-module', 'ytd-promoted-sparkles-web-renderer' ], networkPatterns: [ // 修正正则表达式闭合 /\/\/doubleclick\.net\//, /youtube\.com\/api\/stats\/ads/, /google\.com\/pagead\//, // 正确闭合的正则表达式 /\/adservice\.google\./ ], whitelistPatterns: [ /googlevideo\.com\/videoplayback/, /\/vi\/.+\/hqdefault\.jpg\??/ ] } }, adSelectors: [ 'div[id^="ad-"]:not([id*="-container"])', 'ytd-ad-slot-renderer', 'div.ytd-in-feed-ad-layout-renderer', 'ins.adsbygoogle' ] }; class AdBlocker { constructor() { this.currentHost = location.hostname; this.blockedCount = 0; if (this.isTargetDomain()) this.initialize(); } isTargetDomain() { return Object.keys(SecurityConfig.protectedDomains) .some(d => this.currentHost.includes(d)); } initialize() { this.setupMutationObserver(); this.hijackNetworkRequests(); this.injectStatusWidget(); } setupMutationObserver() { new MutationObserver(mutations => { mutations.forEach(({ addedNodes }) => { addedNodes.forEach(node => { if (node.nodeType === 1) this.purgeAds(node); }); }); this.deepScan(); }).observe(document, { childList: true, subtree: true }); } purgeAds(root) { const targets = root.querySelectorAll( this.getCompositeSelectors() ); targets.forEach(el => { if (!this.isVideoContainer(el)) { el.remove(); this.blockedCount++; } }); } getCompositeSelectors() { const domainConfig = SecurityConfig.protectedDomains[this.currentHost]; return [ ...SecurityConfig.adSelectors, ...(domainConfig?.selectors || []) ].join(', '); } hijackNetworkRequests() { // 拦截fetch const nativeFetch = window.fetch; window.fetch = async (input, init) => { const reqUrl = input.url || input; if (this.shouldBlockRequest(reqUrl)) { console.warn('[BLOCKED] Fetch:', reqUrl); return new Response(null, { status: 403 }); } return nativeFetch(input, init); }; // 拦截XHR const nativeOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { this._requestURL = url; nativeOpen.apply(this, arguments); }; const nativeSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(...args) { if (this._requestURL && this.shouldBlockRequest(this._requestURL)) { console.warn('[BLOCKED] XHR:', this._requestURL); this.abort(); return; } nativeSend.apply(this, args); }; } shouldBlockRequest(url) { const domainConfig = SecurityConfig.protectedDomains[this.currentHost]; if (!domainConfig) return false; // 白名单优先 if (domainConfig.whitelistPatterns.some(p => p.test(url))) return false; // 广告规则匹配 return domainConfig.networkPatterns.some(p => p.test(url)); } injectStatusWidget() { const icon = document.createElement('div'); icon.className = 'adblocker-status-icon'; document.body.appendChild(icon); // 添加交互事件... } } new AdBlocker(); })();