// ==UserScript== // @name 视频网站去广告 - 爱奇艺/优酷/腾讯/咪咕/PPTV/1905/芒果/哔哩 // @name:zh-CN 视频网站去广告 - 爱奇艺/优酷/腾讯/咪咕/PPTV/1905/芒果/哔哩 // @namespace https://github.com/ // @version 1.0.0 // @description 自动去除多个视频网站的广告,包括爱奇艺、优酷、腾讯视频、咪咕视频、PPTV、1905电影网、芒果TV、哔哩哔哩 // @description:zh-CN 自动去除多个视频网站的广告,包括爱奇艺、优酷、腾讯视频、咪咕视频、PPTV、1905电影网、芒果TV、哔哩哔哩 // @author WorkBuddy AI // @license MIT // @match *://*.iqiyi.com/* // @match *://*.youku.com/* // @match *://v.qq.com/* // @match *://*.miguvideo.com/* // @match *://*.pptv.com/* // @match *://*.1905.com/* // @match *://*.mgtv.com/* // @match *://*.bilibili.com/* // @match *://*.bilibili.tv/* // @grant unsafeWindow // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_openInTab // @grant GM_notification // @grant GM_setClipboard // @grant GM_log // @run-at document-start // @noframes // ==/UserScript== (function() { 'use strict'; // 配置对象 const config = { debug: false, removeBannerAds: true, removeVideoAds: true, removePopupAds: true, removeFloatingAds: true, skipPreRollAds: true, skipMidRollAds: true, autoPlayNext: false, showNotifications: true, whitelist: [] }; // 日志函数 function log(...args) { if (config.debug) { console.log('[Video Ad Remover]', ...args); } } // 通知函数 function notify(message, title = '视频去广告') { if (config.showNotifications && typeof GM_notification === 'function') { GM_notification({ text: message, title: title, timeout: 3000 }); } } // 添加自定义CSS样式 function addCustomStyles() { const css = ` /* 通用广告隐藏样式 */ .ad-container, .ad-banner, .ad-wrapper, .ad-slot, .adsbygoogle, .advertisement, .ad-area, .ad-box, .iqy-ad, .youku-ad, .tencent-ad, .migu-ad, .pptv-ad, .mgtv-ad, .bilibili-ad, [class*="ad-"], [class*="Ad-"], [class*="AD-"], [id*="ad-"], [id*="Ad-"], [id*="AD-"], [data-ad], [data-ad-type], .popup-ad, .floating-ad, .video-ad, .pre-roll-ad, .mid-roll-ad, .post-roll-ad, .ad-skip-button, .ad-close-button, .ad-mask { display: none !important; visibility: hidden !important; opacity: 0 !important; width: 0 !important; height: 0 !important; position: absolute !important; left: -9999px !important; top: -9999px !important; pointer-events: none !important; } /* 视频播放器优化 */ .video-player, .player-container, .bilibili-player, .iqiyi-player, .youku-player, .tencent-player { overflow: hidden !important; } /* 去除广告占位符 */ .ad-placeholder { display: none !important; } /* 页面布局优化 */ body.ad-active, html.ad-active { overflow: auto !important; } `; if (typeof GM_addStyle === 'function') { GM_addStyle(css); } else { const style = document.createElement('style'); style.textContent = css; document.head.appendChild(style); } } // 爱奇艺广告处理 function handleIqiyi() { log('处理爱奇艺广告'); // 移除广告元素 const adSelectors = [ '.iqy-ad', '.ad-container', '.ad-banner', '.ad-slot', '.ad-wrapper', '[class*="iqy-ad-"]', '[data-ad-type="iqiyi"]', '.popup-ad', '.floating-ad' ]; // 监控DOM变化 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除爱奇艺广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); // 初始移除 adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除爱奇艺广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告 if (video.currentTime < 60 && video.duration < 90) { const skipBtn = document.querySelector('.qiyi-skip-ad, .skip-ad, .ad-skip-button'); if (skipBtn) { skipBtn.click(); log('点击跳过爱奇艺广告按钮'); } else if (video.currentTime < 60) { video.currentTime = 60; log('跳过爱奇艺片头广告'); } } } }, 1000); } // 优酷广告处理 function handleYouku() { log('处理优酷广告'); const adSelectors = [ '.youku-ad', '.yk-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="youku-ad-"]', '[data-ad-type="youku"]', '.popup-ad', '.floating-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除优酷广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除优酷广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告 if (video.currentTime < 75 && video.duration < 100) { const skipBtn = document.querySelector('.youku-skip-ad, .skip-ad, .ad-skip-button'); if (skipBtn) { skipBtn.click(); log('点击跳过优酷广告按钮'); } else if (video.currentTime < 75) { video.currentTime = 75; log('跳过优酷片头广告'); } } } }, 1000); } // 腾讯视频广告处理 function handleTencent() { log('处理腾讯视频广告'); const adSelectors = [ '.tencent-ad', '.qq-ad', '.tx-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="tencent-ad-"]', '[class*="qq-ad-"]', '[data-ad-type="tencent"]', '.popup-ad', '.floating-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除腾讯视频广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除腾讯视频广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告(腾讯视频通常是45-60秒) if (video.currentTime < 60 && video.duration < 90) { const skipBtn = document.querySelector('.tencent-skip-ad, .skip-ad, .tx-skip-ad'); if (skipBtn) { skipBtn.click(); log('点击跳过腾讯视频广告按钮'); } else if (video.currentTime < 60) { video.currentTime = 60; log('跳过腾讯视频片头广告'); } } } }, 1000); } // 哔哩哔哩广告处理 function handleBilibili() { log('处理哔哩哔哩广告'); const adSelectors = [ '.bilibili-ad', '.bili-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="bilibili-ad-"]', '[class*="bili-ad-"]', '[data-ad-type="bilibili"]', '.popup-ad', '.recommend-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除哔哩哔哩广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除哔哩哔哩广告元素:', selector); }); }); // 哔哩哔哩通常没有片头广告,但可能有推广视频 setInterval(() => { const video = document.querySelector('video'); if (video) { // 如果是推广视频,跳过 const title = document.title || ''; if (title.includes('推广') || title.includes('广告')) { const nextBtn = document.querySelector('.next-button, .next-episode'); if (nextBtn) { nextBtn.click(); log('跳过哔哩哔哩推广视频'); } } } }, 2000); } // 芒果TV广告处理 function handleMangoTV() { log('处理芒果TV广告'); const adSelectors = [ '.mango-ad', '.mgtv-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="mango-ad-"]', '[class*="mgtv-ad-"]', '[data-ad-type="mango"]', '.popup-ad', '.floating-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除芒果TV广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除芒果TV广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告 if (video.currentTime < 60 && video.duration < 90) { const skipBtn = document.querySelector('.mango-skip-ad, .skip-ad, .mgtv-skip-ad'); if (skipBtn) { skipBtn.click(); log('点击跳过芒果TV广告按钮'); } else if (video.currentTime < 60) { video.currentTime = 60; log('跳过芒果TV片头广告'); } } } }, 1000); } // 咪咕视频广告处理 function handleMigu() { log('处理咪咕视频广告'); const adSelectors = [ '.migu-ad', '.mg-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="migu-ad-"]', '[data-ad-type="migu"]', '.popup-ad', '.floating-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除咪咕视频广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除咪咕视频广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告 if (video.currentTime < 60 && video.duration < 90) { const skipBtn = document.querySelector('.migu-skip-ad, .skip-ad, .mg-skip-ad'); if (skipBtn) { skipBtn.click(); log('点击跳过咪咕视频广告按钮'); } else if (video.currentTime < 60) { video.currentTime = 60; log('跳过咪咕视频片头广告'); } } } }, 1000); } // PPTV广告处理 function handlePPTV() { log('处理PPTV广告'); const adSelectors = [ '.pptv-ad', '.pp-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="pptv-ad-"]', '[data-ad-type="pptv"]', '.popup-ad', '.floating-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除PPTV广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除PPTV广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告 if (video.currentTime < 60 && video.duration < 90) { const skipBtn = document.querySelector('.pptv-skip-ad, .skip-ad, .pp-skip-ad); if (skipBtn) { skipBtn.click(); log('点击跳过PPTV广告按钮'); } else if (video.currentTime < 60) { video.currentTime = 60; log('跳过PPTV片头广告'); } } } }, 1000); } // 1905电影网广告处理 function handle1905() { log('处理1905电影网广告'); const adSelectors = [ '.ad-1905', '.movie-ad', '.ad-container', '.ad-banner', '.ad-slot', '[class*="1905-ad"]', '[data-ad-type="1905"]', '.popup-ad', '.floating-ad' ]; const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { adSelectors.forEach((selector) => { const elements = node.querySelectorAll ? node.querySelectorAll(selector) : []; elements.forEach((el) => { el.remove(); log('移除1905电影网广告元素:', selector); }); }); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); adSelectors.forEach((selector) => { document.querySelectorAll(selector).forEach((el) => { el.remove(); log('初始移除1905电影网广告元素:', selector); }); }); // 处理视频广告 setInterval(() => { const video = document.querySelector('video'); if (video) { // 跳过片头广告 if (video.currentTime < 60 && video.duration < 90) { const skipBtn = document.querySelector('.1905-skip-ad, .skip-ad, .movie-skip-ad'); if (skipBtn) { skipBtn.click(); log('点击跳过1905电影网广告按钮'); } else if (video.currentTime < 60) { video.currentTime = 60; log('跳过1905电影网片头广告'); } } } }, 1000); } // 通用广告拦截器 function setupAdBlocker() { // 拦截广告请求 if (typeof GM_xmlhttpRequest !== 'undefined') { // 这里可以添加广告URL拦截逻辑 log('广告请求拦截器已启用'); } // 监控网络请求(通过覆盖XMLHttpRequest和fetch) if (unsafeWindow.XMLHttpRequest) { const originalOpen = unsafeWindow.XMLHttpRequest.prototype.open; unsafeWindow.XMLHttpRequest.prototype.open = function(method, url) { // 检查是否是广告URL if (url && isAdUrl(url)) { log('拦截广告请求:', url); // 返回一个不会真正发送的请求 this.open = function() {}; this.send = function() {}; this.abort = function() {}; return; } return originalOpen.apply(this, arguments); }; } if (unsafeWindow.fetch) { const originalFetch = unsafeWindow.fetch; unsafeWindow.fetch = function(input, init) { const url = typeof input === 'string' ? input : input.url; if (url && isAdUrl(url)) { log('拦截fetch广告请求:', url); return Promise.reject(new Error('广告请求被拦截')); } return originalFetch.call(this, input, init); }; } } // 判断是否是广告URL function isAdUrl(url) { const adPatterns = [ /ad\./i, /ads\./i, /adserver/i, /doubleclick/i, /googleads/i, /advertising/i, /advertise/i, /\.ad\.[a-z]+$/i, /\/ad\//i, /\/ads\//i, /\/advert\//i, /analytics/i, /tracking/i, /beacon/i, /pixel/i, /impression/i, /click\./i, /sponsor/i, /promotion/i, /banner/i, /popup/i, /float/i, /pre-roll/i, /mid-roll/i, /post-roll/i ]; return adPatterns.some(pattern => pattern.test(url)); } // 初始化函数 function init() { log('视频去广告脚本初始化'); // 添加自定义样式 addCustomStyles(); // 设置广告拦截器 setupAdBlocker(); // 根据当前网站执行相应的处理函数 const hostname = window.location.hostname; if (hostname.includes('iqiyi.com')) { handleIqiyi(); notify('爱奇艺广告拦截已启用'); } else if (hostname.includes('youku.com')) { handleYouku(); notify('优酷广告拦截已启用'); } else if (hostname.includes('v.qq.com') || hostname.includes('qq.com')) { handleTencent(); notify('腾讯视频广告拦截已启用'); } else if (hostname.includes('miguvideo.com')) { handleMigu(); notify('咪咕视频广告拦截已启用'); } else if (hostname.includes('pptv.com')) { handlePPTV(); notify('PPTV广告拦截已启用'); } else if (hostname.includes('1905.com')) { handle1905(); notify('1905电影网广告拦截已启用'); } else if (hostname.includes('mgtv.com')) { handleMangoTV(); notify('芒果TV广告拦截已启用'); } else if (hostname.includes('bilibili.com') || hostname.includes('bilibili.tv')) { handleBilibili(); notify('哔哩哔哩广告拦截已启用'); } else { // 通用处理 log('通用广告处理'); const observer = new MutationObserver(() => { document.querySelectorAll('.ad-container, .ad-banner, .ad-slot, [class*="ad-"], [id*="ad-"]').forEach(el => { el.remove(); }); }); observer.observe(document.body, { childList: true, subtree: true }); } log('脚本初始化完成'); } // 等待DOM加载完成后执行 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // 添加菜单命令(如果可用) if (typeof GM_registerMenuCommand === 'function') { GM_registerMenuCommand('开启调试模式', () => { config.debug = !config.debug; notify(`调试模式 ${config.debug ? '已开启' : '已关闭'}`); }); GM_registerMenuCommand('重新扫描广告', () => { init(); notify('已重新扫描页面广告'); }); GM_registerMenuCommand('关于此脚本', () => { GM_openInTab('https://github.com/', { active: true }); }); } })();