您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Logs and exports all ad/tracker URLs (.js, links, redirects, fetch) with download support even on redirecting pages
// ==UserScript== // @name Advanced Ad Tracker Logger // @namespace elite.scan.logger.v2 // @version 2.0 // @description Logs and exports all ad/tracker URLs (.js, links, redirects, fetch) with download support even on redirecting pages // @author Abdelali // @match *://*/* // @grant GM_download // ==/UserScript== (function () { 'use strict'; const findings = { scripts: [], adLinks: [], externalLinks: [], redirects: [], }; const adKeywords = ['ads', 'adserver', 'doubleclick', 'tracker', 'analytics', 'revbid', 'coinzilla', 'adskeeper', 'banner', 'prebid', 'rtb']; function isAdOrTracker(url) { return adKeywords.some(kw => url.toLowerCase().includes(kw)); } function logFinding(type, url, context = '') { if (!findings[type].some(entry => entry.url === url)) { findings[type].push({ url, context }); } } // Watch script injections const scanDOM = () => { try { document.querySelectorAll('script[src]').forEach(script => { const src = script.src; if (isAdOrTracker(src)) { logFinding('scripts', src, 'script tag'); } }); document.querySelectorAll('a[href]').forEach(link => { const href = link.href; if (isAdOrTracker(href)) { logFinding('adLinks', href, 'anchor'); } else if (href.startsWith('http') && new URL(href).hostname !== location.hostname) { logFinding('externalLinks', href, 'external anchor'); } }); // Try to inspect iframes document.querySelectorAll('iframe').forEach(iframe => { try { const doc = iframe.contentDocument; if (doc) { doc.querySelectorAll('script[src]').forEach(script => { if (isAdOrTracker(script.src)) { logFinding('scripts', script.src, 'iframe script'); } }); } } catch (e) { // cross-origin, skip silently } }); } catch (e) {} }; const observer = new MutationObserver(scanDOM); observer.observe(document, { childList: true, subtree: true }); setInterval(scanDOM, 3000); // Catch delayed loads // Hook fetch & XHR const origFetch = window.fetch; window.fetch = function () { const url = arguments[0]; if (typeof url === 'string' && isAdOrTracker(url)) { logFinding('scripts', url, 'fetch'); } return origFetch.apply(this, arguments); }; const origOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function (method, url) { if (isAdOrTracker(url)) { logFinding('scripts', url, 'XHR'); } return origOpen.apply(this, arguments); }; // Catch redirections ['pushState', 'replaceState'].forEach(fn => { const orig = history[fn]; history[fn] = function () { const url = arguments[2]; if (typeof url === 'string' && isAdOrTracker(url)) { logFinding('redirects', url, `history.${fn}`); } return orig.apply(this, arguments); }; }); window.addEventListener('hashchange', () => { const url = location.href; if (isAdOrTracker(url)) { logFinding('redirects', url, 'hashchange'); } }); // Export function with force download using Blob function forceDownload(content, filename = 'ad_scan.json') { const blob = new Blob([content], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.style.display = 'none'; document.body.appendChild(a); a.click(); setTimeout(() => { URL.revokeObjectURL(url); a.remove(); }, 1000); } // Button window.addEventListener('load', () => { const btn = document.createElement('button'); btn.textContent = '📦 Export Ads Log'; Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: 999999, padding: '10px', background: '#111', color: '#fff', border: 'none', borderRadius: '5px', cursor: 'pointer', }); btn.onclick = () => { const data = JSON.stringify(findings, null, 2); forceDownload(data, `ad_scan_${location.hostname}.json`); }; document.body.appendChild(btn); }); })();