Greasy Fork 还支持 简体中文。

URL Modifier for Search Engines

Modify URLs in search results of search engines

目前為 2024-01-01 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name URL Modifier for Search Engines
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.7.3
  5. // @description Modify URLs in search results of search engines
  6. // @author Domenic
  7. // @match *://www.google.com/search?*q=*
  8. // @match *://searx.tiekoetter.com/search*
  9. // @match *://search.disroot.org/search*
  10. // @match *://www.startpage.com/search*
  11. // @match *://www.startpage.com/sp/search*
  12. // @match *://search.brave.com/search*
  13. // @match *://duckduckgo.com
  14. // @match *://duckduckgo.com/?*q=*
  15. // @grant none
  16. // @run-at document-end
  17. // @license GPL-2.0-only
  18. // ==/UserScript==
  19.  
  20. (function() {
  21. 'use strict';
  22.  
  23. // Define URL modification rules
  24. const urlModificationRules = [
  25. {
  26. matchRegex: /^https?:\/\/www\.reddit\.com(.*)/,
  27. replaceWith: 'https://old.reddit.com$1'
  28. },
  29. {
  30. matchRegex: /^https?:\/\/(en(.m)?|simple)\.wikipedia.org\/wiki\/(?!Special:Search)(\w+)/,
  31. replaceWith: 'https://www.wikiwand.com/en/$3'
  32. },
  33. {
  34. matchRegex: /^https?:\/\/zh(\.m)?\.wikipedia\.org\/(zh-hans|wiki)\/(.*)/,
  35. replaceWith: 'https://www.wikiwand.com/zh-hans/$3'
  36. },
  37. {
  38. matchRegex: /^https?:\/\/((\w+\.)?medium\.com\/.*)/,
  39. replaceWith: 'https://freedium.cfd/https://$1'
  40. },
  41. {
  42. matchRegex: /^https?:\/\/((.*)arxiv\.org\/pdf|arxiv-export-lb.library.cornell.edu\/(pdf|abs))\/(\d{4}\.\d{4,5}(v\d)?)(.*)/,
  43. replaceWith: 'https://arxiv.org/abs/$4'
  44. },
  45. {
  46. matchRegex: /^https?:\/\/(ieeexplore\.ieee\.org\/document\/\d+)\//,
  47. replaceWith: 'https://$1'
  48. }
  49. // Add more rules here as needed
  50. ];
  51.  
  52. // Define enhanced selector rules for each search engine
  53. const selectorRules = {
  54. 'google': [
  55. {
  56. selector: 'div.yuRUbf div span a',
  57. childSelector: 'div.byrV5b cite',
  58. updateChildText: true,
  59. useTopLevelDomain: true, // Flag for using top-level domain
  60. containProtocol: true
  61. }
  62. ],
  63. 'searx': [
  64. {
  65. selector: 'article a.url_wrapper',
  66. childSelector: '.url_i1',
  67. updateChildText: true,
  68. useTopLevelDomain: true,
  69. containProtocol: true
  70. },
  71. {
  72. selector: 'h3 a'
  73. }
  74. ],
  75. 'startpage': [
  76. {
  77. selector: 'a.w-gl__result-url.result-link',
  78. updateText: true
  79. },
  80. {
  81. selector: 'a.w-gl__result-title.result-link'
  82. }
  83. ],
  84. 'brave': [
  85. {
  86. selector: 'a.h.svelte-1dihpoi',
  87. childSelector: 'cite.snippet-url.svelte-1ygzem6 span.netloc.text-small-bold.svelte-1ygzem6',
  88. updateChildText: true,
  89. useTopLevelDomain: true,
  90. containProtocol: false
  91. }
  92. ],
  93. 'duckduckgo': [
  94. {
  95. selector: 'a.eVNpHGjtxRBq_gLOfGDr.LQNqh2U1kzYxREs65IJu'
  96. },
  97. {
  98. selector: 'div.mwuQiMOjmFJ5vmN6Vcqw.LQVY1Jpkk8nyJ6HBWKAk a.Rn_JXVtoPVAFyGkcaXyK',
  99. childSelector: 'span',
  100. updateChildText: true,
  101. useTopLevelDomain: true,
  102. containProtocol: true
  103. }
  104. ]
  105. // Additional search engines can be defined here...
  106. };
  107.  
  108. // User-defined list of search engine instance URLs
  109. const searchEngines = {
  110. 'google': [
  111. 'www.google.com'
  112. ],
  113. 'searx': [
  114. 'searx.tiekoetter.com',
  115. 'search.disroot.org'
  116. ],
  117. 'startpage': [
  118. 'www.startpage.com'
  119. ],
  120. 'brave': [
  121. 'search.brave.com'
  122. ],
  123. 'duckduckgo': [
  124. 'duckduckgo.com'
  125. ],
  126. // ... more search engines
  127. };
  128.  
  129. // Function to modify URLs and optionally text
  130. const modifyUrls = (engine) => {
  131. const selectors = selectorRules[engine];
  132. if (selectors) {
  133. selectors.forEach(rule => {
  134. document.querySelectorAll(rule.selector).forEach(element => {
  135. urlModificationRules.forEach(urlRule => {
  136. let newHref = "error";
  137. if (element.href && urlRule.matchRegex.test(element.href)) {
  138. newHref = element.href.replace(urlRule.matchRegex, urlRule.replaceWith);
  139. element.href = newHref;
  140.  
  141. // Check if text content update is needed
  142. if (rule.updateText) {
  143. let textContent = rule.useTopLevelDomain ? extractTopLevelDomain(newHref, rule.containProtocol) : newHref;
  144. element.textContent = textContent;
  145. }
  146.  
  147. // Check if child text content update is needed
  148. if (rule.updateChildText && rule.childSelector) {
  149. let childElement = element.querySelector(rule.childSelector);
  150. if (childElement) {
  151. let textContent = rule.useTopLevelDomain ? extractTopLevelDomain(newHref, rule.containProtocol) : newHref;
  152. childElement.textContent = textContent;
  153. }
  154. }
  155. }
  156. });
  157. });
  158. });
  159. }
  160. };
  161.  
  162. // Function to extract top-level domain from a URL
  163. const extractTopLevelDomain = (url, containProtocol) => {
  164. let regex = containProtocol ? /^(https?:\/\/[^\/]+)/ : /^(?:https?:\/\/)?([^\/]+)/;
  165. let matches = url.match(regex);
  166. return matches ? matches[1] : url;
  167. };
  168.  
  169. // Improved function to determine the search engine
  170. const getSearchEngine = () => {
  171. let host = window.location.host;
  172.  
  173. for (let engine in searchEngines) {
  174. if (searchEngines[engine].some(instanceHost => host.includes(instanceHost))) {
  175. return engine;
  176. }
  177. }
  178. };
  179.  
  180. // Run the script for the current search engine
  181. const currentEngine = getSearchEngine();
  182.  
  183. if (currentEngine) {
  184. modifyUrls(currentEngine);
  185.  
  186. // Observe DOM changes to handle dynamic content
  187. const observer = new MutationObserver(() => modifyUrls(currentEngine));
  188. observer.observe(document.body, { childList: true, subtree: true });
  189. }
  190. })();