// ==UserScript== // @name 新浪彩票去广告去注册登录去付费 // @namespace https://lotto.sina.cn/ // @version 1.1 // @description 去除新浪彩票网站的广告横幅、弹窗广告、登录注册弹窗、付费阅读限制等干扰元素 // @author WorkBuddy // @match *://lotto.sina.cn/* // @match *://sports.sina.com.cn/lottery/* // @match *://*.sina.com.cn/*lottery* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; // 需要隐藏的元素选择器列表 const HIDE_SELECTORS = [ // 通用广告弹窗 '.popup-ad', '.ad-popup', '[class*="ad-"]', '[class*="advertisement"]', '[id*="ad-"]', '[id*="advertisement"]', // 登录注册弹窗 '.login-popup', '.login-modal', '.login-box', '.register-popup', '.register-modal', '.register-box', '.signin-popup', '.signup-popup', '[class*="login-box"]', '[class*="login-modal"]', '[class*="login-dialog"]', '[class*="login-modal"]', '[class*="register-modal"]', '[class*="signup"]', '[id*="login-popup"]', '[id*="login-modal"]', '[id*="login-box"]', '[id*="register-popup"]', '[id*="register-modal"]', // 浮动广告 '.float-ad', '.floating-ad', '.float-banner', '.suspension-ad', '[class*="float-"]', '[class*="suspension"]', '[class*="fixed-ad"]', // 横幅广告 '.banner-ad', '.top-ad', '.bottom-ad', '[class*="banner-"]', '[class*="top-banner"]', '[class*="bottom-banner"]', // 弹窗遮罩 '.modal-backdrop', '.modal-overlay', '.popup-overlay', '.mask-layer', '[class*="modal-backdrop"]', '[class*="modal-overlay"]', // 推广下载 '.app-download', '.download-popup', '[class*="app-download"]', '[class*="download-"]', // iframe广告 'iframe[src*="ad"]', 'iframe[src*="banner"]', 'iframe[src*="promotion"]', 'iframe[src*="sina.com.cn"][width="300"]', 'iframe[src*="sina.com.cn"][height="250"]', // 右侧悬浮 '.right-float', '.left-float', '[class*="right-float"]', '[class*="left-float"]', // 通知弹窗 '.toast', '.notification-popup', '[class*="toast-"]', '[class*="notification-"]', // 关闭按钮关联的弹窗 '.pop-close', '.close-popup', '[class*="close-btn"]', // 视频广告 '.video-ad', '[class*="video-ad"]', '[class*="preroll"]', // 推送通知弹窗 '.push-notification', '[class*="push-notif"]', '[class*="subscribe-"]', // 调查问卷 '.survey-popup', '[class*="survey-"]', // 新浪通行证登录 '.sina-login', '#SI_FLY_LOGIN', '[id*="passport"]', '[id*="sinaSSO"]', '[class*="SSO"]', // 新浪爱彩登录 '.aicai-login', '[class*="aicai-login"]', '[id*="aicai"]', // 通用弹窗类 '.dialog', '.dialog-popup', '.layer-popup', '[class*="layer-popup"]', '[class*="pop-dialog"]', // 页面遮罩 '#page-mask', '.page-mask', '[class*="page-mask"]', '[id*="mask"]', ]; // 要隐藏的CSS类名模式(正则) const HIDE_CLASS_PATTERNS = [ /ad-/i, /advertisement/i, /popup/i, /modal/i, /dialog/i, /float/i, /banner/i, /overlay/i, /mask/i, /login/i, /register/i, /signin/i, /signup/i, /suspension/i, /toast/i, /notification/i, /download/i, /preroll/i, /survey/i, /layer/i, /passport/i, /SSO/i, /aicai/i, ]; // 需要移除的DOM元素ID模式 const REMOVE_ID_PATTERNS = [ /ad/i, /popup/i, /modal/i, /dialog/i, /float/i, /banner/i, /login/i, /register/i, /signin/i, /signup/i, /mask/i, /overlay/i, /layer/i, /passport/i, /sinaSSO/i, /aicai/i, ]; // 日志开关 const DEBUG = false; const log = DEBUG ? console.log.bind(console, '[SinaLottery Cleaner]') : function() {}; /** * 隐藏指定选择器的元素 */ function hideElements() { HIDE_SELECTORS.forEach(selector => { try { const elements = document.querySelectorAll(selector); elements.forEach(el => { if (el && el.style.display !== 'none') { el.style.display = 'none'; log('隐藏元素:', selector); } }); } catch (e) { // 无效选择器,忽略 } }); } /** * 根据类名模式隐藏元素 */ function hideByClassPatterns() { const allElements = document.querySelectorAll('*'); allElements.forEach(el => { if (el.className && typeof el.className === 'string') { const classes = el.className.split(/\s+/); for (const cls of classes) { for (const pattern of HIDE_CLASS_PATTERNS) { if (pattern.test(cls)) { el.style.display = 'none'; log('隐藏匹配类名的元素:', cls); break; } } } } }); } /** * 根据ID模式移除元素 */ function removeByIdPatterns() { const allElements = document.querySelectorAll('*'); allElements.forEach(el => { if (el.id) { for (const pattern of REMOVE_ID_PATTERNS) { if (pattern.test(el.id)) { el.style.display = 'none'; log('隐藏匹配ID的元素:', el.id); break; } } } }); } /** * 隐藏新浪通行证相关元素 */ function hideSinaPassport() { const passportElements = [ '#SI_FLY_LOGIN', '#SI_Fly_ZDCard', '.sina-login-wrap', '.sina-login-content', '[id*="sinaSSO"]', '[id*="passport"]', '[class*="sina-login"]', '[class*="passport-login"]', 'iframe[src*="passport"]', 'iframe[src*="sinaSSO"]', ]; passportElements.forEach(selector => { try { const elements = document.querySelectorAll(selector); elements.forEach(el => { el.style.display = 'none'; log('隐藏新浪通行证元素:', selector); }); } catch (e) { // 忽略无效选择器 } }); } /** * 隐藏常见的弹窗和遮罩 */ function hidePopupsAndOverlays() { // 隐藏所有遮罩层 const overlays = document.querySelectorAll('[class*="mask"], [class*="overlay"], [class*="backdrop"]'); overlays.forEach(el => { const tagName = el.tagName.toLowerCase(); // 跳过body和html if (tagName === 'body' || tagName === 'html') return; el.style.display = 'none'; }); // 隐藏可能的弹窗内容 const popups = document.querySelectorAll('[class*="popup-content"], [class*="dialog-content"], [class*="modal-content"]'); popups.forEach(el => { // 检查父元素是否是弹窗 let parent = el.parentElement; let isPopup = false; while (parent && parent !== document.body) { if (parent.className && typeof parent.className === 'string') { if (/popup|dialog|modal|layer/i.test(parent.className)) { isPopup = true; break; } } parent = parent.parentElement; } if (isPopup) { el.style.display = 'none'; } }); } /** * 隐藏iframe广告 */ function hideIframeAds() { const iframes = document.querySelectorAll('iframe'); iframes.forEach(iframe => { const src = iframe.src || ''; // 隐藏包含广告相关URL的iframe if (/ad|banner|promotion|cpc|cpm|display/i.test(src)) { iframe.style.display = 'none'; log('隐藏广告iframe:', src); } // 隐藏尺寸为典型广告尺寸的iframe const width = parseInt(iframe.width) || 0; const height = parseInt(iframe.height) || 0; if ((width === 300 && height === 250) || // 中矩形 (width === 728 && height === 90) || // 横幅 (width === 160 && height === 600) || // 宽幅 skyscraper (width === 300 && height === 600) || // 半页 (width === 320 && height === 50)) { // 移动端横幅 iframe.style.display = 'none'; log('隐藏典型广告尺寸iframe:', width + 'x' + height); } }); } /** * 隐藏新浪爱彩相关弹窗 */ function hideAicaiPopups() { const aicaiSelectors = [ '[class*="aicai-login"]', '[class*="aicai-popup"]', '[class*="aicai-modal"]', '[id*="aicai-login"]', '[id*="aicai-popup"]', '[id*="aicai-modal"]', '.aicai-dialog', '#aicai-dialog', '[class*="ac-login"]', '[id*="ac-login"]', ]; aicaiSelectors.forEach(selector => { try { const elements = document.querySelectorAll(selector); elements.forEach(el => { el.style.display = 'none'; log('隐藏爱彩相关元素:', selector); }); } catch (e) { // 忽略无效选择器 } }); } /** * 隐藏通知和提示 */ function hideNotifications() { const notificationSelectors = [ '.toast-container', '.notification-container', '[class*="toast-"]', '[class*="notification-"]', '.tip-popup', '[class*="tip-"]', '.guide-tip', '[class*="guide-"]', '.welcome-tip', '[class*="welcome-"]', ]; notificationSelectors.forEach(selector => { try { const elements = document.querySelectorAll(selector); elements.forEach(el => { el.style.display = 'none'; log('隐藏通知元素:', selector); }); } catch (e) { // 忽略无效选择器 } }); } /** * 去除付费阅读限制 */ function removePaywall() { log('开始去除付费限制...'); // 付费墙/付费提示选择器 const paywallSelectors = [ // 通用付费墙 '.paywall', '.pay-wall', '.paywall-overlay', '.paywall-mask', '.paywall-box', '.paywall-container', '.paywall-content', '[class*="paywall"]', '[class*="pay-wall"]', '[id*="paywall"]', '[id*="pay-wall"]', // 付费提示 '.pay-tip', '.pay-notice', '.pay-hint', '.pay-info', '.paid-content', '.pay-required', '[class*="pay-tip"]', '[class*="pay-notice"]', '[class*="pay-hint"]', // 订阅提示 '.subscribe-tip', '.subscribe-notice', '.subscription-tip', '.vip-tip', '.vip-notice', '[class*="subscribe-tip"]', '[class*="subscription"]', '[class*="vip-tip"]', // 充值提示 '.recharge-tip', '.coin-tip', '.credit-tip', '[class*="recharge"]', '[class*="coin-tip"]', // 登录付费混合 '.login-pay', '.login-to-read', '.login-to-view', '[class*="login-to-read"]', '[class*="login-to-view"]', // 正文付费遮罩(渐变模糊遮罩) '.article-content-cover', '.content-cover', '.text-cover', '.read-more-cover', '[class*="content-cover"]', '[class*="article-cover"]', // 全文阅读限制 '.full-text', '.read-more', '.view-full', '[class*="read-more"]', '[class*="view-more"]', // 付费弹窗 '.pay-popup', '.pay-modal', '.pay-dialog', '[class*="pay-popup"]', '[class*="pay-modal"]', // 新浪爱彩付费 '.aicai-pay', '.ac-pay', '[class*="aicai-pay"]', '[class*="ac-pay"]', '[id*="aicai-pay"]', // 赞赏/打赏提示 '.reward-tip', '.reward-notice', '[class*="reward-tip"]', '[class*="donate"]', // 付费图标 '.pay-icon', '.vip-icon', '.lock-icon', '[class*="lock-icon"]', ]; paywallSelectors.forEach(selector => { try { const elements = document.querySelectorAll(selector); elements.forEach(el => { el.style.display = 'none'; log('隐藏付费元素:', selector); }); } catch (e) { // 忽略无效选择器 } }); // 移除付费遮罩的渐变效果 const gradientSelectors = [ '[style*="gradient"]', '[style*="mask-image"]', '[style*="-webkit-mask-image"]', '[style*="blur"]', ]; gradientSelectors.forEach(selector => { try { const elements = document.querySelectorAll(selector); elements.forEach(el => { const style = el.getAttribute('style') || ''; if (/gradient|blur|mask/i.test(style)) { el.style.background = ''; el.style.backgroundImage = ''; el.style.webkitMaskImage = ''; el.style.maskImage = ''; el.style.filter = ''; log('移除遮罩样式'); } }); } catch (e) { // 忽略 } }); // 移除内容高度限制(付费墙常用技巧:限制内容高度 + 遮罩) const contentRestricted = document.querySelectorAll('[style*="height"][style*="overflow"]'); contentRestricted.forEach(el => { const style = el.getAttribute('style') || ''; if (/height:\s*\d+px|height:\s*\d+em/i.test(style)) { el.style.maxHeight = 'none'; el.style.height = 'auto'; el.style.overflow = 'visible'; log('移除内容高度限制'); } }); // 移除带有付费限制类的元素的样式限制 const restrictedElements = document.querySelectorAll('[class*="restricted"], [class*="limit"], [class*="locked"]'); restrictedElements.forEach(el => { el.style.maxHeight = 'none'; el.style.height = 'auto'; el.style.overflow = 'visible'; log('移除限制样式'); }); // 处理正文内容容器 - 移除 overflow: hidden const articleContents = document.querySelectorAll('.article-content, .article-body, .article-text, .content-body, [class*="article-body"], [class*="content-body"]'); articleContents.forEach(el => { const computedStyle = window.getComputedStyle(el); if (computedStyle.overflow === 'hidden' || computedStyle.maxHeight) { el.style.maxHeight = 'none'; el.style.overflow = 'visible'; log('处理正文容器'); } }); // 移除付费提示文字(节点内容检测) const payKeywords = ['付费', '购买', '订阅', 'VIP', '充值', '查看全文', '阅读更多', '解锁', '付费阅读', '购买全文', '订阅查看', '此内容付费可见', '登录后阅读', '登录查看完整内容']; const textNodes = document.evaluate( '//text()[contains(., "付费") or contains(., "购买") or contains(., "订阅") or contains(., "VIP") or contains(., "充值") or contains(., "查看全文")]', document.body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null ); for (let i = 0; i < textNodes.snapshotLength; i++) { const node = textNodes.snapshotItem(i); if (node.parentElement && !['SCRIPT', 'STYLE', 'NOSCRIPT'].includes(node.parentElement.tagName)) { const parent = node.parentElement; const parentClass = (parent.className || '').toLowerCase(); const parentId = (parent.id || '').toLowerCase(); // 如果父元素有付费相关类名,隐藏整个元素 if (/pay|wall|subscribe|vip|restricted|locked|tip|notice|cover|mask|overlay/i.test(parentClass + parentId)) { if (parent.style.display !== 'none') { parent.style.display = 'none'; log('隐藏付费提示元素'); } } } } log('付费限制去除完成'); } /** * 执行所有清理操作 */ function cleanPage() { log('开始清理页面...'); hideElements(); hideByClassPatterns(); removeByIdPatterns(); hideSinaPassport(); hidePopupsAndOverlays(); hideIframeAds(); hideAicaiPopups(); hideNotifications(); removePaywall(); // 去除付费限制 log('页面清理完成'); } /** * 创建 MutationObserver 监听 DOM 变化 */ function setupObserver() { let debounceTimer = null; const observer = new MutationObserver((mutations) => { // 防抖处理 clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { // 检查是否有显著的变化 let hasSignificantChange = false; for (const mutation of mutations) { if (mutation.addedNodes.length > 0) { for (const node of mutation.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE) { hasSignificantChange = true; break; } } } if (hasSignificantChange) break; } if (hasSignificantChange) { cleanPage(); } }, 100); }); // 配置观察者 const config = { childList: true, subtree: true }; // 开始观察 observer.observe(document.documentElement, config); log('MutationObserver 已启动'); return observer; } /** * 主函数 */ function main() { log('脚本开始执行'); // 页面加载时执行清理 cleanPage(); // 设置 MutationObserver 监听动态内容 setupObserver(); // 定时清理(备用方案) setInterval(cleanPage, 3000); // 监听常见的弹窗触发事件 document.addEventListener('click', (e) => { // 阻止可能触发登录的点击 const target = e.target; if (target.tagName === 'A' || target.tagName === 'BUTTON') { const text = (target.textContent || '').toLowerCase(); const className = (target.className || '').toLowerCase(); const id = (target.id || '').toLowerCase(); // 如果点击的是登录/注册按钮,记录日志但不阻止 if (/login|登录|signin|register|注册|signup/i.test(text + className + id)) { log('检测到登录/注册相关点击:', text); } } }, true); log('脚本初始化完成'); } // 页面加载完成后执行 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', main); } else { main(); } })();