CSDN滚啊

屏蔽搜索结果中出现的一切有关CSDN的选项(支持Google、百度、Bing)

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

  1. // ==UserScript==
  2. // @name CSDN滚啊
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.5
  5. // @description 屏蔽搜索结果中出现的一切有关CSDN的选项(支持Google、百度、Bing)
  6. // @author xiaoma
  7. // @match *://*/*
  8. // @grant none
  9. // @run-at document-end
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. /*
  14. MIT License
  15.  
  16. Copyright (c) 2024 xiaoma
  17.  
  18. Permission is hereby granted, free of charge, to any person obtaining a copy
  19. of this software and associated documentation files (the "Software"), to deal
  20. in the Software without restriction, including without limitation the rights
  21. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  22. copies of the Software, and to permit persons to whom the Software is
  23. furnished to do so, subject to the following conditions:
  24.  
  25. The above copyright notice and this permission notice shall be included in all
  26. copies or substantial portions of the Software.
  27.  
  28. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  29. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  30. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  31. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  32. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  33. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  34. SOFTWARE.
  35. */
  36.  
  37. (function () {
  38. 'use strict';
  39.  
  40. // 百度搜索结果选择器
  41. const baiduSelectors = {
  42. results: '#content_left > div.result, #content_left > div.result-op',
  43. title: 'h3.t a, h3.c-title a',
  44. url: '.c-showurl'
  45. };
  46.  
  47. // 屏蔽CSDN链接
  48. function blockCSDNLinks() {
  49. const csdnDomain = 'csdn.net';
  50. const csdnKeywords = ['csdn'];
  51.  
  52. // 通用链接检查策略(适用于Google、Bing等)
  53. const links = document.querySelectorAll('a');
  54. links.forEach(link => {
  55. let shouldBlock = false;
  56.  
  57. // 检查链接href是否包含CSDN域名
  58. if (link.href && link.href.toLowerCase().includes(csdnDomain)) {
  59. shouldBlock = true;
  60. }
  61.  
  62. // 检查链接文本是否包含CSDN关键词
  63. if (link.textContent && csdnKeywords.some(keyword =>
  64. link.textContent.toLowerCase().includes(keyword))) {
  65. shouldBlock = true;
  66. }
  67.  
  68. if (shouldBlock) {
  69. // 查找不同搜索引擎的搜索结果容器
  70. const resultItem = link.closest('.b_ans, .b_widgetContainer, .b_algo') || // Bing
  71. link.closest('.MjjYud') || // Google (这个类名相对稳定)
  72. link.closest('[data-rpos]') || // Google备选方案
  73. link.closest('[jscontroller="SC7lYd"]') || // Google另一个备选
  74. link.closest('div[class*="result"]'); // 通用备选方案
  75.  
  76. if (resultItem) {
  77. resultItem.style.display = 'none';
  78. console.log('已屏蔽CSDN搜索结果:', resultItem);
  79. }
  80. }
  81. });
  82.  
  83. // 百度搜索特殊处理(保持原有逻辑)
  84. const baiduResults = document.querySelectorAll(baiduSelectors.results);
  85. baiduResults.forEach(result => {
  86. const titleEl = result.querySelector(baiduSelectors.title);
  87. const urlEl = result.querySelector(baiduSelectors.url);
  88. if (!titleEl && !urlEl) return;
  89.  
  90. const titleText = titleEl?.textContent?.toLowerCase() || '';
  91. const urlText = urlEl?.textContent?.toLowerCase() || '';
  92. const href = titleEl?.href?.toLowerCase() || '';
  93.  
  94. if (titleText.includes('csdn') || urlText.includes('csdn') || href.includes('csdn.net')) {
  95. result.style.display = 'none';
  96. console.log('已屏蔽百度CSDN搜索结果:', result);
  97. }
  98. });
  99.  
  100. // 额外检查:通过文本内容查找CSDN相关结果
  101. const textElements = document.querySelectorAll('*');
  102. textElements.forEach(element => {
  103. // 只检查包含CSDN文本的特定元素
  104. if (element.textContent &&
  105. (element.textContent.includes('CSDN博客') ||
  106. element.textContent.includes('blog.csdn.net'))) {
  107.  
  108. // 查找父级搜索结果容器
  109. const resultContainer = element.closest('.MjjYud') ||
  110. element.closest('[data-rpos]') ||
  111. element.closest('.b_ans, .b_widgetContainer, .b_algo') ||
  112. element.closest('div[class*="result"]');
  113.  
  114. if (resultContainer) {
  115. resultContainer.style.display = 'none';
  116. console.log('通过文本内容屏蔽CSDN结果:', resultContainer);
  117. }
  118. }
  119. });
  120.  
  121. // 隐藏百度右侧栏
  122. const rightColumn = document.getElementById('content_right');
  123. if (rightColumn) {
  124. rightColumn.style.display = 'none';
  125. }
  126. }
  127.  
  128. // 防抖函数
  129. function debounce(func, wait) {
  130. let timeout;
  131. return function () {
  132. const context = this;
  133. const args = arguments;
  134. clearTimeout(timeout);
  135. timeout = setTimeout(() => {
  136. func.apply(context, args);
  137. }, wait);
  138. };
  139. }
  140.  
  141. // 滚动事件监听
  142. window.addEventListener('scroll', debounce(function () {
  143. const scrollHeight = Math.max(
  144. document.documentElement.scrollHeight,
  145. document.body.scrollHeight
  146. );
  147. const scrollTop = window.pageYOffset ||
  148. document.documentElement.scrollTop ||
  149. document.body.scrollTop;
  150. const clientHeight = window.innerHeight ||
  151. document.documentElement.clientHeight ||
  152. document.body.clientHeight;
  153.  
  154. if (scrollHeight - scrollTop - clientHeight < 100) {
  155. requestAnimationFrame(() => {
  156. blockCSDNLinks();
  157. });
  158. }
  159. }, 200));
  160.  
  161. // DOM变化监听
  162. const observer = new MutationObserver(debounce(function (mutations) {
  163. mutations.forEach(function (mutation) {
  164. if (mutation.addedNodes.length) {
  165. blockCSDNLinks();
  166. }
  167. });
  168. }, 200));
  169.  
  170. const config = {
  171. childList: true,
  172. subtree: true
  173. };
  174.  
  175. const targetNode = document.body;
  176. observer.observe(targetNode, config);
  177.  
  178. // 初始执行
  179. blockCSDNLinks();
  180. })();