- // ==UserScript==
- // @name 搜索引擎官网净化器-增强版
- // @namespace http://tampermonkey.net/
- // @version 1.4
- // @description 精准识别官网/智能屏蔽虚假结果(支持百度/谷歌/必应)
- // @author AI助手优化版
- // @license MIT
- // @match *://www.baidu.com/*
- // @match *://www.google.com/*
- // @match *://www.bing.com/*
- // @grant GM_addStyle
- // @grant GM.getValue
- // @grant GM.setValue
- // @grant GM.registerMenuCommand
- // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
- // @noframes
- // ==/UserScript==
-
- (function() {
- 'use strict';
-
- // 增强视觉样式
- GM_addStyle(`
- .official-site-mark {
- background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%) !important;
- border-radius: 12px;
- padding: 2px 8px;
- color: white;
- font-size: 12px;
- margin-left: 8px;
- position: relative;
- top: -1px;
- animation: popIn 0.3s ease;
- }
- @keyframes popIn {
- 0% { transform: scale(0); }
- 90% { transform: scale(1.1); }
- 100% { transform: scale(1); }
- }
- .dangerous-result {
- position: relative;
- opacity: 0.3;
- transition: opacity 0.3s;
- }
- .dangerous-result::after {
- content: "⚠️ 危险结果已模糊处理";
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%,-50%);
- color: #d32f2f;
- font-weight: bold;
- background: rgba(255,255,255,0.9);
- padding: 8px 16px;
- border-radius: 4px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
- }
- `);
-
- // 动态配置中心
- const SearchEngineConfig = {
- 'www.baidu.com': {
- selectors: {
- container: '#content_left',
- results: '.c-container, .result-op, [mu]',
- title: 'h3.t, h3 a',
- officialMark: [
- '.c-icon-certified', // 百度官方认证图标
- { type: 'text', pattern: /官网$/ },
- { type: 'attribute', selector: '[data-landmark="official"]' }
- ],
- dangerMark: [
- '.c-tips-icon-warning', // 百度风险提示图标
- { type: 'text', pattern: /(彩票|网赚|代购|刷单)/ }
- ]
- },
- dangerDomains: [
- /\.(xyz|top|loan|tk|ml)/i,
- /(wangzhan|seo|baidu\.zhuanlan)/i
- ],
- officialDomains: [
- /\.(gov|edu)\.cn$/,
- /(baidu|alibaba|tencent|jd)\.com$/
- ]
- },
- 'www.google.com': {
- selectors: {
- container: '#search',
- results: '.g:not(.ULSxyf)',
- title: 'h3, [role="heading"]',
- officialMark: [
- '.VuuXrf', // Google认证标记
- { type: 'text', pattern: / - Official Site$/i },
- { type: 'attribute', selector: '[aria-label="Verified"]' }
- ],
- dangerMark: [
- '.iDjcJe[aria-label="Warning"]', // Google危险提示
- { type: 'text', pattern: /(casino|porn|pharmacy)/i }
- ]
- },
- dangerDomains: [
- /\.(xyz|top|bid|loan)/i,
- /(freevpn|cheapdrugs|fake)/i
- ],
- officialDomains: [
- /\.(gov|edu|mil)$/,
- /(google|microsoft|apple)\.com$/
- ]
- },
- 'www.bing.com': {
- selectors: {
- container: '#b_results',
- results: '.b_algo',
- title: 'h2 > a',
- officialMark: [
- '[aria-label="官方站点"]',
- { type: 'text', pattern: /Official Site/i }
- ],
- dangerMark: [
- '.b_attribution > .b_dotext[href*="danger"]',
- { type: 'text', pattern: /(赌博|诈骗)/i }
- ]
- },
- dangerDomains: [
- /\.(stream|gq|cf)/i,
- /(poker|bitcoin)/i
- ],
- officialDomains: [
- /\.(gov|edu)/i,
- /(microsoft|bing)\.com$/i
- ]
- }
- };
-
- class SearchGuard {
- constructor() {
- this.engine = location.hostname;
- this.config = SearchEngineConfig[this.engine];
- if (!this.config) return;
-
- this.initState();
- this.enhanceUI();
- this.setupObservers();
- }
-
- async initState() {
- this.enabled = await GM.getValue('searchGuardEnabled', true);
- this.debugMode = await GM.getValue('debugMode', false);
- this.log('初始化完成');
- }
-
- log(...args) {
- if (this.debugMode) console.log('[SearchGuard]', ...args);
- }
-
- enhanceUI() {
- // 添加调试面板
- const panel = document.createElement('div');
- panel.innerHTML = `
- <div style="position:fixed;top:20px;right:20px;background:#fff;
- padding:15px;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,0.1);
- z-index:9999;font-family:Arial;">
- <h3 style="margin:0 0 10px;font-size:15px;">🔍 搜索防护</h3>
- <label style="display:flex;align-items:center;gap:8px;margin:6px 0;">
- <input type="checkbox" ${this.enabled ? 'checked' : ''}>
- <span>启用智能过滤</span>
- </label>
- <button style="margin-top:8px;padding:4px 8px;"
- onclick="document.dispatchEvent(new Event('searchGuardRefresh'))">
- 立即刷新结果
- </button>
- </div>
- `;
- document.body.appendChild(panel);
- panel.querySelector('input').addEventListener('change', e => {
- this.enabled = e.target.checked;
- GM.setValue('searchGuardEnabled', this.enabled);
- this.processAllResults();
- });
- }
-
- setupObservers() {
- // 双保险监听:MutationObserver + 轮询检查
- const mainObserver = new MutationObserver(() => this.processAllResults());
- const container = document.querySelector(this.config.selectors.container);
- if (container) mainObserver.observe(container, { childList: true, subtree: true });
-
- // 定时检查DOM变化(应对动态加载)
- setInterval(() => this.processAllResults(), 2000);
-
- // 自定义刷新事件
- document.addEventListener('searchGuardRefresh', () => this.processAllResults());
- }
-
- processAllResults() {
- if (!this.enabled) return;
- $(this.config.selectors.results).each((i, el) => {
- if (el.dataset.processed) return;
- this.analyzeResult(el);
- el.dataset.processed = true;
- });
- }
-
- analyzeResult(element) {
- const url = this.getResultUrl(element);
- if (!url) return;
-
- // 多重检测逻辑
- const isOfficial = this.checkOfficial(element, url);
- const isDangerous = this.checkDangerous(element, url);
-
- if (isDangerous) {
- this.markAsDangerous(element);
- } else if (isOfficial) {
- this.markAsOfficial(element);
- }
- }
-
- getResultUrl(element) {
- const link = element.querySelector(this.config.selectors.title)?.href;
- try {
- return new URL(link).hostname;
- } catch {
- return null;
- }
- }
-
- checkOfficial(element, url) {
- // 特征检测 + 域名白名单
- return this.config.selectors.officialMark.some(marker => {
- if (typeof marker === 'string') {
- return element.querySelector(marker) !== null;
- }
- switch (marker.type) {
- case 'text':
- return marker.pattern.test(element.textContent);
- case 'attribute':
- return element.querySelector(marker.selector) !== null;
- default:
- return false;
- }
- }) || this.config.officialDomains.some(domain => domain.test(url));
- }
-
- checkDangerous(element, url) {
- // 风险特征 + 危险域名
- return this.config.selectors.dangerMark.some(marker => {
- if (typeof marker === 'string') {
- return element.querySelector(marker) !== null;
- }
- switch (marker.type) {
- case 'text':
- return marker.pattern.test(element.textContent);
- case 'attribute':
- return element.querySelector(marker.selector) !== null;
- default:
- return false;
- }
- }) || this.config.dangerDomains.some(domain => domain.test(url));
- }
-
- markAsOfficial(element) {
- const title = element.querySelector(this.config.selectors.title);
- if (!title || title.querySelector('.official-site-mark')) return;
-
- const mark = document.createElement('span');
- mark.className = 'official-site-mark';
- mark.textContent = {
- 'www.baidu.com': '官方认证',
- 'www.google.com': 'Verified',
- 'www.bing.com': 'Official'
- }[this.engine];
- title.appendChild(mark);
- }
-
- markAsDangerous(element) {
- element.classList.add('dangerous-result');
- element.querySelector('a')?.addEventListener('click', e => {
- e.preventDefault();
- alert('访问此网站可能存在风险!');
- });
- }
- }
-
- // 启动防护(带错误恢复机制)
- let guard;
- function initGuard() {
- try {
- guard = new SearchGuard();
- } catch (error) {
- console.error('[SearchGuard] 初始化失败,2秒后重试:', error);
- setTimeout(initGuard, 2000);
- }
- }
- setTimeout(initGuard, 1000);
-
- })();