搜索引擎过滤器

过滤搜索页垃圾信息,并将重定向网址解析为直接网址

  1. // ==UserScript==
  2. // @name SearchEngine-Filter
  3. // @name:zh-CN 搜索引擎过滤器
  4. // @namespace https://greasyfork.org/zh-CN/users/42351
  5. // @version 1.8
  6. // @description Filter search page spam, And resolve redirect URL into direct
  7. // @description:zh-CN 过滤搜索页垃圾信息,并将重定向网址解析为直接网址
  8. // @icon64 https://antecer.gitlab.io/amusingdevice/icon/antecer.ico
  9. // @icon https://antecer.gitlab.io/amusingdevice/icon/antecer.ico
  10. // @author Antecer
  11. // @include http*://*.baidu.com*
  12. // @include http*://*.bing.com/search?*
  13. // @grant GM_xmlhttpRequest
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @connect *
  17. // @run-at document-body
  18. // @compatible chrome 测试通过
  19. // @compatible firefox 未测试
  20. // @compatible opera 未测试
  21. // @compatible safari 未测试
  22. // ==/UserScript==
  23.  
  24. (async () => {
  25. // 识别百度网页
  26. if (!location.host.endsWith('baidu.com')) return;
  27. // 识别百度搜索页 与 搜图页
  28. if (!(location.href.includes('baidu.com/s?') || location.href.includes('baidu.com/pcpage/similar?'))) return;
  29. // 读取脚本配置
  30. let scriptCfgs = {
  31. unRedirect: GM_getValue('unRedirect', true), // 反重定向(默认启用)
  32. unExperience: GM_getValue('unExperience', true), // 屏蔽百度经验(默认启用)
  33. unOtherQuery: GM_getValue('unOtherQuery', true), // 屏蔽其他人还在搜(默认启用)
  34. unExpert: GM_getValue('unExpert', true), // 屏蔽百度健康(默认启用)
  35. unHotQuery: GM_getValue('unHotQuery', false), // 屏蔽百度热搜榜(默认禁用)
  36. unSimilar: GM_getValue('unSimilar', false), // 屏蔽相关搜索(默认禁用)
  37. unGame: GM_getValue('unGame', false), // 屏蔽百度游戏(默认禁用)
  38. unTuiguang: GM_getValue('unTuiguang', true), // 屏蔽百度推广(默认启用)
  39. adBlock: GM_getValue('adBlock', true), // 屏蔽广告(默认启用)
  40. unRogue: GM_getValue('unRogue', 'hao123.com|2345.com') // 屏蔽流氓网站(默认启用,清空参数表示禁用)
  41. };
  42.  
  43. // 创建sleep方法(用于async/await的延时处理)
  44. const Sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
  45. // 创建超时变量,防止长时间循环遍历document
  46. const timeoutValue = 10;
  47. // 创建选择器,用于判断element是否已加载
  48. const isBodyLoading = async (css) => {
  49. let timeout = timeoutValue;
  50. while (!document.querySelector(css) && timeout) {
  51. --timeout;
  52. await Sleep(1000);
  53. }
  54. };
  55.  
  56. // 功能模块
  57. const Steps = {
  58. unRedirect: async () => {
  59. await isBodyLoading(`[href*="baidu.com/link?"],[href*="baidu.com/api/proxy?"]`);
  60. let allowUpgrade = document.createElement(`meta`);
  61. allowUpgrade.setAttribute('http-equiv', 'Content-Security-Policy');
  62. allowUpgrade.setAttribute('content', 'upgrade-insecure-requests');
  63. document.head.append(allowUpgrade);
  64. document.querySelectorAll(`[href*="baidu.com/link?"],[href*="baidu.com/api/proxy?"]`).forEach((element) => {
  65. (async (item) => {
  66. let reTry = false;
  67. let thisXhr = GM_xmlhttpRequest({
  68. url: item.href,
  69. method: 'GET',
  70. onreadystatechange: (result) => {
  71. if (result.readyState > 2) {
  72. item.href = result.finalUrl;
  73. thisXhr.abort();
  74. }
  75. },
  76. onerror: (err) => {
  77. reTry = true;
  78. console.error(`[Baidu-Filter] Call HEAD Failed!`, err);
  79. }
  80. });
  81. })(element);
  82. });
  83. },
  84. unExperience: async () => {
  85. await isBodyLoading(`[href*="jingyan.baidu.com"]`);
  86. document.querySelectorAll(`#content_left>div`).forEach((item) => {
  87. if (item.querySelector(`[href*="jingyan.baidu.com"]`)) item.remove();
  88. });
  89. },
  90. unOtherQuery: async () => {
  91. await isBodyLoading(`.result-op`);
  92. document.querySelectorAll(`#content_left>div`).forEach((item) => {
  93. if (item.innerHTML.includes(`>其他人还在搜<`)) item.remove();
  94. });
  95. },
  96. unExpert: async () => {
  97. while (!document.querySelector(`[href*="expert.baidu.com"]`)) await Sleep(1000);
  98. document.querySelectorAll(`#content_left>div`).forEach((item) => {
  99. if (item.querySelector(`[href*="expert.baidu.com"]`)) item.remove();
  100. });
  101. },
  102. unTuiguang: async () => {
  103. while (!document.querySelector(`[data-tuiguang]`)) await Sleep(1000);
  104. document.querySelectorAll(`#content_left>div`).forEach((item) => {
  105. if (item.querySelector(`span[data-tuiguang]`)) item.remove();
  106. });
  107. },
  108. unGame: async()=> {
  109. await isBodyLoading(`a[href*="lewan.baidu.com"]`);
  110. document.querySelectorAll(`#content_left>div`).forEach((item) => {
  111. if (item.querySelector(`a[href*="lewan.baidu.com"]`)) item.remove();
  112. });
  113. },
  114. unHotQuery: async () => {
  115. await isBodyLoading(`[title="百度热榜"]`);
  116. document.querySelectorAll(`#content_right`).forEach((item) => {
  117. if (item.querySelector(`[title="百度热榜"]`)) item.remove();
  118. });
  119. },
  120. unSimilar: async () => {
  121. while (!document.querySelector(`#rs`)) await Sleep(1000);
  122. document.querySelectorAll(`[id="rs"]`).forEach((item) => {
  123. if (item.querySelector(`table a[href^="/s?wd="]`)) item.remove();
  124. });
  125. },
  126. adBlock: async () => {
  127. while (!document.querySelector(`.ec_tuiguang_pplink`)) await Sleep(1000);
  128. document.querySelectorAll(`#content_left>div`).forEach((item) => {
  129. if (item.innerHTML.includes(`>广告</span>`)) item.remove();
  130. });
  131. },
  132. unRogue: async () => {
  133. let timeout = timeoutValue;
  134. let rogueList = scriptCfgs.unRogue;
  135. let rogueRegExp = new RegExp(rogueList);
  136. while (rogueList && timeout) {
  137. --timeout;
  138. let nodes = document.querySelectorAll('a');
  139. for (let i = nodes.length; i > 0; ) {
  140. if (nodes[--i].href.match(rogueRegExp)) {
  141. i = timeout = 0;
  142. }
  143. }
  144. await Sleep(1000);
  145. }
  146. let rList = document.querySelectorAll(`#content_left>div`);
  147. for (let i = rList.length; i > 0; ) {
  148. --i;
  149. let cList = rList[i].querySelectorAll('a');
  150. for (let n = cList.length; n > 0; ) {
  151. --n;
  152. if (cList[n].href.match(rogueRegExp)) {
  153. rList[i].remove();
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. };
  160.  
  161. // 检查并执行已启用的功能
  162. const runScript = async () => {
  163. let loopNum = 3; // 执行次数
  164. let timeout = 5; // 间隔时间
  165. while (loopNum--) {
  166. Object.keys(scriptCfgs).forEach((key) => {
  167. GM_setValue(key, scriptCfgs[key]); // 保存脚本配置
  168. if (scriptCfgs[key]) Steps[key](); // 执行脚本功能
  169. });
  170. for (let i = timeout; i-- > 0; ) await Sleep(1000);
  171. }
  172. };
  173. // 监听页面变化
  174. document.querySelector('title').addEventListener('DOMNodeInserted', () => runScript(), false);
  175. // 运行脚本
  176. runScript();
  177. })();
  178.  
  179. (async()=>{
  180. // 识别必应网页
  181. if (!location.host.endsWith('bing.com')) return;
  182. // 读取脚本配置
  183. let scriptCfgs = {
  184. unRogue: GM_getValue('unRogue', 'hao123.com|2345.com') // 屏蔽流氓网站(默认启用,清空参数表示禁用)
  185. };
  186. // 创建sleep方法(用于async/await的延时处理)
  187. const Sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
  188. // 功能模块
  189. const Steps = {
  190. unRogue: async()=>{
  191. let rogueList = scriptCfgs.unRogue;
  192. let rogueRegExp = new RegExp(rogueList);
  193. let rList = document.querySelectorAll(`main>ol>li`);
  194. for (let i = rList.length; i > 0; ) {
  195. --i;
  196. let cList = rList[i].querySelectorAll('a');
  197. for (let n = cList.length; n > 0; ) {
  198. --n;
  199. if (cList[n].href.match(rogueRegExp)) {
  200. rList[i].remove();
  201. break;
  202. }
  203. }
  204. }
  205. }
  206. };
  207. // 检查并执行已启用的功能
  208. const runScript = async () => {
  209. let loopNum = 3; // 执行次数
  210. let timeout = 5; // 间隔时间
  211. while (loopNum--) {
  212. Object.keys(scriptCfgs).forEach((key) => {
  213. GM_setValue(key, scriptCfgs[key]); // 保存脚本配置
  214. if (scriptCfgs[key]) Steps[key](); // 执行脚本功能
  215. });
  216. for (let i = timeout; i-- > 0; ) await Sleep(1000);
  217. }
  218. };
  219. // 监听页面变化
  220. document.querySelector('title').addEventListener('DOMNodeInserted', () => runScript(), false);
  221. // 运行脚本
  222. runScript();
  223. })();