您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
过滤 X/Twitter 搜索/时间线里的 Solana 合约广告:地址+CA邻近/重复地址/TICKER与版式词多条件命中;域名直拦;白名单;菜单开关
当前为
// ==UserScript== // @name X/Twitter SOL CA Spam Killer (v2.3, stronger heuristics) // @namespace https://x.com/ // @version 2.3.0 // @description 过滤 X/Twitter 搜索/时间线里的 Solana 合约广告:地址+CA邻近/重复地址/TICKER与版式词多条件命中;域名直拦;白名单;菜单开关 // @match https://x.com/* // @match https://twitter.com/* // @run-at document-start // @grant GM_registerMenuCommand // ==/UserScript== (function () { 'use strict'; /*** 配置 ***/ const STORAGE_KEY = 'sol_ca_filter_enabled_v23'; let ENABLED = JSON.parse(localStorage.getItem(STORAGE_KEY) || 'true'); // 域名直拦(出现即视为推广) const BLOCKED_DOMAINS = [ 'okai.hk', 'okai.hk/alpha', 'alpha.mevx.io', 'gmgn.ai', 'gmgn.ai/sol/token', 'gmgn.cc', 'gmgn.org', 'photon-sol.com', 'dexscreener.com', 'birdeye.so', 'rugcheck.xyz', 'pump.fun', 'pumpswap', 't.me' ]; // 拉盘/版式词(命中越多越可疑) const KEYWORDS = [ 'token alert', 'token stats', 'links', 'security', 'mc $', 'market cap', 'vol', 'lp', 'ath', 'watch your entry', 'called at', 'quick buy', 'signal', 'up up up', 'gmgn', 'bonkbot', 'trojan', 'chain: solana', 'dev: holds token', 'mint authority: no', 'freeze authority: no', // 常见 CA 行配套 '📍ca', ' ca:', ' ca:', ' ca,', ' ca,', ' ca;', ' ca;', ' ca>', ' ca>>', 'ca>', ]; // 白名单(避免误杀) const WHITELIST = [ '$smiley', '#smiley' ]; /*** 识别规则 ***/ // Sol 地址:Base58,32~44,不含 0OIl const SOL_ADDR_RE = /\b(?=.{32,44}\b)(?!.*[OIl0])[1-9A-HJ-NP-Za-km-z]{32,44}\b/g; // “CA 近邻地址”——覆盖 : , ; > >> 以及 >、中英文符号、换行/空格 const CA_NEAR_ADDR_RE = /\b(?:ca|contract|合约)\b[\s::,,;;>>»》›]+[\s\r\n]{0,40}[1-9A-HJ-NP-Za-km-z]{32,44}\b/i; // TICKER:$ + 2~8字母 const TICKER_RE = /\$[A-Z]{2,8}\b/; // 归一化:小写,去零宽,统一冒号,压缩空白,转义 > 为 > const normalize = (s) => (s || '') .replace(/>/gi, '>') .toLowerCase() .replace(/[\u200B-\u200D\uFEFF]/g, '') .replace(/[:﹕꞉⦂︰]/g, ':') .replace(/\s+/g, ' ') .trim(); const normKeywords = KEYWORDS.map(normalize); const normWhitelist = WHITELIST.map(normalize); const hasBlockedDomain = (article) => { const links = article.querySelectorAll('a[href], a[role="link"]'); for (const a of links) { const href = (a.getAttribute('href') || a.textContent || '').toLowerCase(); for (const d of BLOCKED_DOMAINS) if (href.includes(d)) return true; } const t = (article.innerText || '').toLowerCase(); return BLOCKED_DOMAINS.some((d) => t.includes(d)); }; const keywordScore = (t) => { let n = 0; for (const k of normKeywords) if (k && t.includes(k)) n++; return n; }; const hitWhitelist = (t) => normWhitelist.some((w) => w && t.includes(w)); function isSpamArticle(article) { const raw = article.innerText || article.textContent || ''; if (!raw) return false; // 域名直拦 if (hasBlockedDomain(article)) return true; const text = normalize(raw); if (hitWhitelist(text)) return false; // 找出地址与重复次数 const addrs = (raw.match(SOL_ADDR_RE) || []); const addrCountMap = {}; for (const a of addrs) addrCountMap[a] = (addrCountMap[a] || 0) + 1; const repeatedAddr = Object.values(addrCountMap).some(c => c >= 2); // 规则 A:CA 邻近地址(CA: / CA, / CA; / CA> / CA>> / Ca> 等) if (CA_NEAR_ADDR_RE.test(raw)) return true; if (addrs.length) { // 规则 B:同一地址在同条里重复出现(截图里的“贴两遍/三遍”) if (repeatedAddr) return true; // 规则 C:地址 + TICKER 或 版式词(得分阈值) const score = keywordScore(text); const hasTicker = TICKER_RE.test(raw); if (hasTicker && score >= 1) return true; // 地址 + $TICKER + ≥1 版式词 if (!hasTicker && score >= 2) return true; // 地址 + ≥2 版式词 } // 规则 D:即使没有地址,拉盘词极度密集(≥4)也拦 if (!addrs.length && keywordScore(text) >= 4) return true; return false; } /*** DOM 处理 ***/ function hideTweet(article) { if (!article || article.dataset.__solCaHidden === '1') return; article.style.display = 'none'; article.dataset.__solCaHidden = '1'; } function restoreAll() { document.querySelectorAll('article[data-__solCaHidden="1"]').forEach(a => (a.style.display = '')); } function checkArticle(article) { if (!ENABLED || !article || article.dataset.__solCaChecked === '1') return; article.dataset.__solCaChecked = '1'; if (isSpamArticle(article)) hideTweet(article); } function scanAll() { document.querySelectorAll('article[data-testid="tweet"], article[role="article"]').forEach(checkArticle); } const obs = new MutationObserver(muts => { if (!ENABLED) return; for (const m of muts) { for (const node of m.addedNodes) { if (!(node instanceof HTMLElement)) continue; if (node.matches?.('article[data-testid="tweet"], article[role="article"]')) { checkArticle(node); } else { node.querySelectorAll?.('article[data-testid="tweet"], article[role="article"]').forEach(checkArticle); } } } }); function startObserver() { obs.observe(document.documentElement, { childList: true, subtree: true }); } function registerMenu() { if (typeof GM_registerMenuCommand !== 'function') return; GM_registerMenuCommand(`SOL 合约广告过滤:${ENABLED ? '✅ 开启' : '⛔ 关闭'}`, () => {}); GM_registerMenuCommand(ENABLED ? '🔕 关闭过滤' : '🔔 开启过滤', () => { ENABLED = !ENABLED; localStorage.setItem(STORAGE_KEY, JSON.stringify(ENABLED)); ENABLED ? scanAll() : restoreAll(); alert(`SOL 合约广告过滤已${ENABLED ? '开启' : '关闭'}`); }); } function ready(fn) { if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn, { once: true }); else fn(); } ready(() => { registerMenu(); startObserver(); scanAll(); setTimeout(scanAll, 600); setTimeout(scanAll, 2000); setInterval(() => ENABLED && scanAll(), 6000); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址