Greasy Fork

Greasy Fork is available in English.

搜索引擎净化器 v1.60 AI自学习版 (本地缓存+UI管理)

AI自学习+本地缓存+UI管理+防封限速,全面净化搜索结果!

当前为 2025-06-14 提交的版本,查看 最新版本

// ==UserScript==
// @name         搜索引擎净化器 v1.60 AI自学习版 (本地缓存+UI管理)
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  AI自学习+本地缓存+UI管理+防封限速,全面净化搜索结果!
// @author       GPT
// @license      MIT
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM.getValue
// @grant        GM.setValue
// @grant        GM_registerMenuCommand
// ==/UserScript==

(async function () {
    'use strict';

    // ✅ 混淆API Key
    const OPENKEY_API = 'https://openkey.cloud/v1/chat/completions';
    const keyParts = ['sk-', '1ytLN', 'fSpk5R34n', 'jTF628665', '6331c426cAeCb95E266F8D377'];
    const API_KEY = keyParts.join('');

    // 默认黑白名单
    const defaultRules = {
        whitelist: ["google.com", "baidu.com", "microsoft.com", "apple.com", "tencent.com", "alibaba.com", "bing.com", "gov.cn", "edu.cn"],
        blacklist: ["casino", "博彩", "色情", "黄片", "诈骗", "刷单", "网赚", "porn", "xxx", "pharmacy", "freevpn", "cheapdrugs"]
    };

    // 样式注入
    GM_addStyle(`
        .sg-official { background: #2196F3; color: #fff; border-radius: 3px; padding: 2px 6px; font-size: 0.75em; margin-left: 8px; }
        .sg-danger  { opacity: 0.3; position: relative; }
        .sg-danger::after { content: "⚠️危险结果已屏蔽"; position:absolute; left:0;right:0;top:40%;color:red;font-weight:bold; text-align:center; z-index:10;}
        #sg-panel { position:fixed;top:20px;right:20px;background:#fff;padding:10px 20px;box-shadow:0 0 10px #333;border-radius:10px;z-index:99999;font-size:14px }
        #sg-panel button { margin:2px;padding:5px 10px;border-radius:5px; }
    `);

    // 加载本地存储
    let whitelist = JSON.parse(await GM.getValue('whitelist', JSON.stringify(defaultRules.whitelist)));
    let blacklist = JSON.parse(await GM.getValue('blacklist', JSON.stringify(defaultRules.blacklist)));
    let cache = JSON.parse(await GM.getValue('cache', '{}'));
    let lastAPICall = 0;  // 速率限制用

    // 注册UI菜单
    GM_registerMenuCommand("打开净化器管理面板", showUIPanel);

    // UI管理面板
    function showUIPanel() {
        const panel = document.createElement('div');
        panel.id = 'sg-panel';
        panel.innerHTML = `
            <b>净化器管理面板</b><br>
            <button id="clearCache">清空AI缓存</button>
            <button id="exportRules">导出规则</button>
            <button id="closePanel">关闭</button>
        `;
        document.body.appendChild(panel);

        document.getElementById('clearCache').onclick = async () => {
            cache = {};
            await GM.setValue('cache', '{}');
            alert("AI缓存已清空");
        };
        document.getElementById('exportRules').onclick = () => {
            alert("白名单:\n" + whitelist.join('\n') + "\n\n黑名单:\n" + blacklist.join('\n'));
        };
        document.getElementById('closePanel').onclick = () => {
            panel.remove();
        };
    }

    // 主逻辑扫描
    function scanPage() {
        const links = document.querySelectorAll('a[href]');
        links.forEach(link => {
            const domain = extractDomain(link.href);
            const text = (link.textContent || '').trim();
            if (!domain) return;
            const container = link.closest('div, li, article, section') || link;

            if (matchWhitelist(domain, text)) {
                markOfficial(link);
            } else if (matchBlacklist(domain, text)) {
                markDanger(container);
            } else {
                const key = domain + '|' + text;
                if (cache[key]) {
                    cache[key] === 'danger' ? markDanger(container) : markOfficial(link);
                } else {
                    aiJudge(domain, text, container, link);
                }
            }

            // 动态右键学习
            link.addEventListener('contextmenu', async (e) => {
                e.preventDefault();
                const action = prompt(`域名:${domain}\n\n输入 1 加入白名单,输入 2 加入黑名单,其它取消`);
                if (action === '1') {
                    if (!whitelist.includes(domain)) whitelist.push(domain);
                    await GM.setValue('whitelist', JSON.stringify(whitelist));
                    alert("已加入白名单,刷新生效");
                } else if (action === '2') {
                    if (!blacklist.includes(domain)) blacklist.push(domain);
                    await GM.setValue('blacklist', JSON.stringify(blacklist));
                    alert("已加入黑名单,刷新生效");
                }
            }, { once: true });
        });
    }

    function matchWhitelist(domain, text) {
        return whitelist.some(rule => domain.includes(rule) || text.includes(rule));
    }

    function matchBlacklist(domain, text) {
        return blacklist.some(rule => domain.includes(rule) || text.match(new RegExp(rule, 'i')));
    }

    function extractDomain(url) {
        try {
            const u = new URL(url);
            return u.hostname.replace(/^www\./, '');
        } catch {
            return null;
        }
    }

    function markOfficial(link) {
        if (link.querySelector('.sg-official')) return;
        const badge = document.createElement('span');
        badge.className = 'sg-official';
        badge.textContent = '官网';
        link.appendChild(badge);
    }

    function markDanger(container) {
        container.classList.add('sg-danger');
        container.querySelector('a')?.addEventListener('click', e => {
            e.preventDefault();
            alert("已拦截危险链接!");
        }, { once: true });
    }

    // AI判定逻辑,内置速率限制
    async function aiJudge(domain, text, container, link) {
        const key = domain + '|' + text;
        if (Date.now() - lastAPICall < 3000) {
            console.warn("限速中,跳过AI请求");
            return;
        }
        lastAPICall = Date.now();

        const prompt = `请判断以下网址是否存在诈骗、色情、博彩、钓鱼、非法刷单、网赚、虚假贷款、危险下载等问题,只回复"危险"或"安全":
网址: ${domain}
标题: ${text}`;

        try {
            const res = await fetch(OPENKEY_API, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${API_KEY}`
                },
                body: JSON.stringify({
                    model: "gpt-3.5-turbo",
                    messages: [{ role: "user", content: prompt }],
                    temperature: 0
                })
            });

            const result = await res.json();
            const reply = result.choices?.[0]?.message?.content?.trim();
            if (reply.includes("危险")) {
                markDanger(container);
                cache[key] = 'danger';
            } else if (reply.includes("安全")) {
                markOfficial(link);
                cache[key] = 'safe';
            }
            await GM.setValue('cache', JSON.stringify(cache));
        } catch (e) {
            console.error("AI请求失败", e);
        }
    }

    setInterval(scanPage, 1500);
})();