// ==UserScript== // @name YouTube广告拦截器 // @namespace safe-adblock-pro // @version 5.0 // @match *://*.youtube.com/* // @grant none // @run-at document-start // @description 动态监测+请求拦截双重方案,支持最新YouTube广告结构 // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 最新广告特征选择器 (更新于2024) const AD_SELECTORS = [ 'ytd-ad-slot-renderer', 'ytd-rich-item-renderer.ytd-rich-grid-row[is-ad]', // 新版信息流广告 'div.ytd-promoted-sparkles-web-renderer', 'div#player-ads:not(#movie_player)', 'ytd-action-companion-ad-renderer', 'div.ad-showing', // 全屏广告状态 'div.ad-container', // 新版广告容器 'ytm-promoted-sparkles-web-renderer', // 移动端适配 'div.ytp-ad-module', 'div.video-ads.ytp-ad-module' // 播放器内广告 ]; // 广告URL特征黑名单 const AD_URL_PATTERNS = [ /\/pagead\/|\/ad_|\/get_midroll_/, /doubleclick\.net/, /google\.com\/pagead/, /\/ads\//, /\/adformat\//, /\/log_event\?action_type=ad/, /\/generate_204\?ad/ ]; // 动态广告扫描器 const adCleaner = { observer: null, scanInterval: null, init() { // 立即执行首次扫描 this.cleanAds(); // 配置MutationObserver this.observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.addedNodes.length) { this.cleanAds(); } }); }); // 开始监听DOM变化 this.observer.observe(document, { childList: true, subtree: true }); // 定时扫描作为备用方案 this.scanInterval = setInterval(() => this.cleanAds(), 1000); }, cleanAds() { AD_SELECTORS.forEach(selector => { document.querySelectorAll(selector).forEach(element => { this.safeRemove(element, '选择器移除'); }); }); // 处理动态插入的视频广告 this.handleVideoAds(); }, safeRemove(element, reason) { try { if (element) { element.style.display = 'none'; element.remove(); console.log(`[拦截日志] ${reason}: ${element.tagName} 已移除`); } } catch (e) { console.warn('移除元素时出错:', e); } }, handleVideoAds() { // 跳过广告按钮处理 const skipButton = document.querySelector('.ytp-ad-skip-button-modern, .ytp-ad-skip-button'); if (skipButton) { skipButton.click(); console.log('[广告拦截] 已跳过视频广告'); } // 处理全屏广告覆盖 const playerOverlay = document.querySelector('.ytp-ad-player-overlay'); if (playerOverlay) { playerOverlay.style.display = 'none'; } // 强制恢复视频播放 const video = document.querySelector('video'); if (video && video.played && video.currentTime < 1) { video.currentTime = 1e4; video.play().catch(() => {}); } } }; // 网络请求拦截器 const requestBlocker = { init() { // 拦截XHR请求 const originalXHR = window.XMLHttpRequest; window.XMLHttpRequest = class extends originalXHR { open(method, url) { if (AD_URL_PATTERNS.some(pattern => pattern.test(url))) { console.log(`[请求拦截] 已阻止广告请求: ${url}`); return; } super.open(method, url); } }; // 拦截Fetch请求 const originalFetch = window.fetch; window.fetch = async (...args) => { const [resource] = args; const url = typeof resource === 'string' ? resource : resource.url; if (AD_URL_PATTERNS.some(pattern => pattern.test(url))) { console.log(`[请求拦截] 已阻止广告请求: ${url}`); return new Response(null, { status: 403 }); } return originalFetch(...args); }; } }; // 播放器保护模块 const playerProtector = { init() { const observer = new MutationObserver(() => { const player = document.getElementById('movie_player'); if (player) { // 禁用广告自动播放 player.addEventListener('onAdStart', e => e.stopImmediatePropagation()); player.classList.remove('ad-showing'); } }); observer.observe(document.body, { childList: true, subtree: true }); } }; // 初始化所有模块 const init = () => { requestBlocker.init(); playerProtector.init(); adCleaner.init(); }; // 启动脚本 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // 反检测保护 Object.defineProperty(document, 'hidden', { value: false, configurable: true }); Object.defineProperty(document, 'visibilityState', { value: 'visible', configurable: true }); })();