您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
此腳本針對某些網站來阻擋反廣告腳本載入
// ==UserScript== // @name 反廣告攔截腳本阻擋工具 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 此腳本針對某些網站來阻擋反廣告腳本載入 // @author Stars Shine // @match https://dl.pgl823.com/* // @grant none // @run-at document-start // @license MIT // ==/UserScript== (function() { 'use strict'; console.log('Tampermonkey: 反廣告攔截腳本阻擋工具 已啟動。'); // 廣告相關的域名列表 const adDomains = [ 'googlesyndication.com', 'googletagservices.com', 'adservice.google.com', 'doubleclick.net', 'ad.doubleclick.net', 'pagead2.googlesyndication.com', 'tpc.googlesyndication.com', 'googleads.g.doubleclick.net', // 您可以根據需要添加更多常見的廣告域名 // 例如:'cdn.ads.example.com', 'tracker.example.com' ]; // 檢查 URL 是否包含廣告域名 function isAdUrl(url) { return adDomains.some(domain => url.includes(domain)); } // 輔助函式:清除 #aBlock 上的所有類別 function clearABlockClasses() { const aBlock = document.getElementById('aBlock'); if (aBlock && aBlock.className !== '') { aBlock.className = ''; // 直接清空所有類別 console.log('Tampermonkey: 移除了 #aBlock 上的所有類別。'); } } // 1. 覆寫 window.onload 屬性,防止其他腳本設定它 // 這會在原始腳本設定 window.onload 之前執行 Object.defineProperty(window, 'onload', { get: function() { return function() {}; // 返回一個空函式 }, set: function(newValue) { console.log('Tampermonkey: 嘗試設定 window.onload 被阻止。'); }, configurable: true // 允許屬性被重新定義 }); // 2. 覆寫原始的 checkAdVisibility 函式為一個空函式 // 這會阻止原始函式內的邏輯執行 window.checkAdVisibility = function() { console.log('Tampermonkey: checkAdVisibility 函式被 Tampermonkey 腳本阻擋。'); clearABlockClasses(); // 確保 aBlock 元素上的所有類別都被移除 }; // 3. 阻擋 Google AdSense 相關的全局變數和腳本載入 // 覆寫 window.adsbygoogle 陣列,防止 AdSense 腳本初始化 // 這樣 AdSense 腳本在執行時會發現 adsbygoogle 已經被控制,無法正常推送廣告單元 window.adsbygoogle = window.adsbygoogle || []; window.adsbygoogle.length = 0; // 清空可能已存在的內容 window.adsbygoogle.push = function() { console.log('Tampermonkey: window.adsbygoogle.push 被阻擋。'); }; // 4. 覆寫 document.createElement 方法,阻止廣告腳本和 iframe 的創建和載入 // 儲存原始的 createElement 方法,以便在非廣告情況下使用 const originalCreateElement = document.createElement; document.createElement = function(tagName) { // 呼叫原始的 createElement 方法創建元素 const element = originalCreateElement.apply(this, arguments); const lowerTagName = tagName.toLowerCase(); // 如果創建的是 <script> 或 <iframe> 標籤 if (lowerTagName === 'script' || lowerTagName === 'iframe') { // 在元素被添加到 DOM 之前,檢查其 src 屬性 // 使用 Object.defineProperty 來攔截 src 屬性的設置 Object.defineProperty(element, 'src', { get: function() { return this._src || ''; }, set: function(value) { // 檢查是否為廣告相關的腳本或 iframe URL if (isAdUrl(value)) { console.log(`Tampermonkey: 偵測到廣告 ${lowerTagName} 載入嘗試,已阻擋:`, value); // 阻止設置 src,使其無法載入 this._src = ''; // 清空 src if (lowerTagName === 'script') { this.type = 'text/plain'; // 阻止腳本執行,可以通過設置 type 為非 JavaScript 類型 } return; // 阻止繼續設置 src } this._src = value; // 設置正常的 src }, configurable: true // 允許屬性被重新定義 }); } return element; // 返回創建的元素 }; // 5. 攔截 XMLHttpRequest 請求 const originalXHRopen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { if (isAdUrl(url)) { console.log('Tampermonkey: 偵測到廣告 XHR 請求,已阻擋:', url); // 阻止請求發送,或者讓它指向一個無害的地址 // 這裡我們直接返回一個空的 open 函式,阻止真正的請求被配置 return; } // 呼叫原始的 open 方法 return originalXHRopen.apply(this, arguments); }; // 6. 攔截 Fetch API 請求 const originalFetch = window.fetch; window.fetch = function(input, init) { let url; if (typeof input === 'string') { url = input; } else if (input instanceof Request) { url = input.url; } else { // 處理其他類型的輸入,儘管通常是字串或 Request 物件 url = String(input); } if (isAdUrl(url)) { console.log('Tampermonkey: 偵測到廣告 Fetch 請求,已阻擋:', url); // 返回一個空的 Promise.reject 或 Promise.resolve,模擬請求失敗或成功但無內容 // 這裡返回一個被拒絕的 Promise,模擬網路錯誤 return Promise.reject(new TypeError('Failed to fetch (blocked by Tampermonkey)')); // 或者可以返回一個成功的 Promise,但內容為空: // return Promise.resolve(new Response('', { status: 200 })); } // 呼叫原始的 fetch 方法 return originalFetch.apply(this, arguments); }; // 7. 移除頁面上已存在的或動態添加的廣告元素,並持續監控 #aBlock 類別 const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // 處理新增節點 if (mutation.addedNodes) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // 確保是元素節點 // 移除 .adsbygoogle 類別的元素 node.querySelectorAll('.adsbygoogle').forEach(function(adElement) { console.log('Tampermonkey: 偵測到並移除 .adsbygoogle 元素。', adElement); adElement.remove(); }); // 移除常見的廣告 iframe node.querySelectorAll('iframe[src*="googlesyndication.com"], iframe[src*="doubleclick.net"]').forEach(function(iframe) { console.log('Tampermonkey: 偵測到並移除廣告 iframe。', iframe); iframe.remove(); }); // 如果新增的節點是 #aBlock 或包含 #aBlock,則清除其類別 if (node.id === 'aBlock' || node.querySelector('#aBlock')) { clearABlockClasses(); } } }); } // 處理屬性變化 (特別針對 #aBlock 的 class 屬性) if (mutation.type === 'attributes' && mutation.attributeName === 'class') { if (mutation.target.id === 'aBlock') { // 如果 #aBlock 的 class 屬性被修改了,立即清空它 clearABlockClasses(); } } }); }); // 開始觀察整個文檔的子節點變化 (childList) 和子樹 (subtree) // 同時也觀察屬性變化 (attributes),這樣可以捕捉到 className 的直接賦值 observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true, // 監控屬性變化 attributeFilter: ['class'] // 只監控 class 屬性的變化 }); // 在 DOMContentLoaded 時執行一次清理,以確保移除初始載入的廣告元素 window.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.adsbygoogle').forEach(function(adElement) { console.log('Tampermonkey: DOMContentLoaded 時偵測到並移除 .adsbygoogle 元素。', adElement); adElement.remove(); }); document.querySelectorAll('iframe[src*="googlesyndication.com"], iframe[src*="doubleclick.net"]').forEach(function(iframe) { console.log('Tampermonkey: DOMContentLoaded 時偵測到並移除廣告 iframe。', iframe); iframe.remove(); }); // 在 DOMContentLoaded 時也檢查並移除 aBlock 上的所有類別 clearABlockClasses(); }); // 8. 嘗試在頁面載入前注入 CSS 來隱藏廣告元素 // 這種方法可以在 JavaScript 執行之前就提供視覺上的阻擋 const style = document.createElement('style'); style.textContent = ` .adsbygoogle, [id*="google_ads_iframe"], /* 針對 AdSense 的 iframe ID 模式 */ iframe[src*="googlesyndication.com"], iframe[src*="doubleclick.net"] { display: none !important; width: 0 !important; height: 0 !important; overflow: hidden !important; visibility: hidden !important; pointer-events: none !important; /* 阻止任何互動 */ } `; // 將 style 標籤添加到文檔的頭部或根元素,使其盡早生效 document.documentElement.appendChild(style); // 9. 阻止 #aBlock 元素重新添加 'hidden' 或 'ad-block' 類別 // 覆寫 setAttribute 方法 const originalSetAttribute = Element.prototype.setAttribute; Element.prototype.setAttribute = function(name, value) { if (this.id === 'aBlock' && name.toLowerCase() === 'class') { const newClasses = value.split(' ').filter(cls => cls !== 'hidden' && cls !== 'ad-block').join(' '); if (newClasses !== value) { console.log(`Tampermonkey: 阻止 #aBlock 設置 class 屬性,移除了 'hidden'/'ad-block'。原始值: "${value}", 新值: "${newClasses}"`); return originalSetAttribute.call(this, name, newClasses); } } return originalSetAttribute.apply(this, arguments); }; // 覆寫 classList.add 方法 const originalClassListAdd = DOMTokenList.prototype.add; DOMTokenList.prototype.add = function() { if (this.ownerElement && this.ownerElement.id === 'aBlock') { const classesToAdd = Array.from(arguments); const filteredClasses = classesToAdd.filter(cls => cls !== 'hidden' && cls !== 'ad-block'); if (filteredClasses.length < classesToAdd.length) { console.log(`Tampermonkey: 阻止 #aBlock 添加 'hidden'/'ad-block' 類別。嘗試添加: "${classesToAdd.join(' ')}", 實際添加: "${filteredClasses.join(' ')}"`); } if (filteredClasses.length > 0) { return originalClassListAdd.apply(this, filteredClasses); } return; // 不添加任何類別 } return originalClassListAdd.apply(this, arguments); }; // 覆寫 classList.remove 方法,確保它能正常移除其他類別 const originalClassListRemove = DOMTokenList.prototype.remove; DOMTokenList.prototype.remove = function() { return originalClassListRemove.apply(this, arguments); }; // 覆寫 classList.toggle 方法 const originalClassListToggle = DOMTokenList.prototype.toggle; DOMTokenList.prototype.toggle = function(token, force) { if (this.ownerElement && this.ownerElement.id === 'aBlock' && (token === 'hidden' || token === 'ad-block')) { console.log(`Tampermonkey: 阻止 #aBlock 執行 toggle 'hidden'/'ad-block' 類別。`); return false; // 返回 false 表示沒有添加/移除 } return originalClassListToggle.apply(this, arguments); }; // 10. 立即執行一次清理,以防 #aBlock 在腳本載入時就存在並帶有類別 // 由於 @run-at document-start,這會盡可能早地執行 clearABlockClasses(); })();