您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Clean up Google Search spam links
- // ==UserScript==
- // @name Google Spam Filter
- // @name:vi Dọn dẹp link rác Google Search
- // @namespace http://tampermonkey.net/
- // @version 1.6
- // @description Clean up Google Search spam links
- // @description:vi Dọn dẹp link rác trên Google Search
- // @author Yuusei
- // @icon https://www.google.com/favicon.ico
- // @match https://www.google.com/search*
- // @grant none
- // @license GPL-3.0-only
- // ==/UserScript==
- (function() {
- 'use strict';
- // options domains
- const spamDomains = new Set([
- '.fr',
- '.pl',
- ]);
- // cache for URLs checked
- const urlCache = new Map();
- const CACHE_EXPIRY = 12 * 60 * 60 * 1000; // 12 hours
- const DEBOUNCE_DELAY = 250; // debounce time
- // check if url is spam
- function isSpamUrl(url) {
- if (!url) return false;
- const now = Date.now();
- // check cache first
- const cached = urlCache.get(url);
- if (cached) {
- if (now - cached.timestamp < CACHE_EXPIRY) {
- return cached.result;
- }
- urlCache.delete(url);
- }
- const urlLower = url.toLowerCase();
- const isSpam = Array.from(spamDomains).some(domain => urlLower.includes(domain));
- // save output to cache
- urlCache.set(url, {
- result: isSpam,
- timestamp: now
- });
- return isSpam;
- }
- // debounce function to prevent calling too many times
- function debounce(func, wait) {
- let timeout;
- return function(...args) {
- clearTimeout(timeout);
- timeout = setTimeout(() => func.apply(this, args), wait);
- };
- }
- // filter and hide spam results
- const filterSpamResults = debounce(() => {
- // select all search results
- const searchResults = document.querySelectorAll('#search .g, #rso .g');
- let spamCount = 0;
- const totalResults = searchResults.length;
- searchResults.forEach(result => {
- const elements = {
- link: result.querySelector('a'),
- cite: result.querySelector('cite'),
- title: result.querySelector('.oewGkc, .LC20lb'),
- snippet: result.querySelector('.VwiC3b')
- };
- const isSpam = elements.link && (
- isSpamUrl(elements.link.href) ||
- isSpamUrl(elements.cite?.textContent) ||
- isSpamUrl(elements.title?.textContent) ||
- isSpamUrl(elements.snippet?.textContent)
- );
- if (isSpam) {
- result.style.display = 'none';
- spamCount++;
- }
- });
- // show notification about the number of spam links filtered
- if (spamCount > 0) {
- const percentage = Math.round((spamCount / totalResults) * 100);
- console.log(`Cleaned ${spamCount}/${totalResults} spam results (${percentage}%)`);
- }
- }, DEBOUNCE_DELAY);
- // run when page loaded
- window.addEventListener('DOMContentLoaded', filterSpamResults);
- // observe content changes (Google dynamic loading)
- const observer = new MutationObserver((mutations) => {
- if (mutations.some(mutation => mutation.addedNodes.length > 0)) {
- filterSpamResults();
- }
- });
- observer.observe(document.documentElement, {
- childList: true,
- subtree: true
- });
- })();