Greasy Fork 还支持 简体中文。

Hide Bot Comments

Removes comments made by bots on websites such as YouTube.

目前為 2022-02-19 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Hide Bot Comments
  3. // @namespace https://theusaf.org
  4. // @version 1.4.0
  5. // @description Removes comments made by bots on websites such as YouTube.
  6. // @author theusaf
  7. // @match https://www.youtube.com/**
  8. // @copyright 2022 theusaf
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. const SITES = Object.freeze({
  14. YOUTUBE: [
  15. /^\s{2,}/, // starts with too much whitespace
  16. /^(\s*@.+)?\s*(https:\/\/[^\s]+|[\n.\s])+$/, // only links and other punctuation
  17. /^(\s*@.+)?\s*[A-Z\s\r\n!]*https:\/\/[^\s]+[A-Z\s\r\n!]*$/, // all caps and a link
  18. /^(\s*@.+)?\s*https:\/\/[^\s]+(\n|.|\s)*([dD]on'?t [mM]iss|Bots for u|Finally|💜|fax|only until|Bots are|:]|I found it :|Yes true)/i, // A link and a random message afterwards
  19. /^(\s*@.+)?\s*(This|[Ww]ow!?)\s*https:\/\/[^\s]+/, // word + link
  20. /^(\s*@.+)?\s*https:\/\/[^\s]+\s*[a-z]+\s*$/, // link + random "word"
  21. /PRIVATE S\*X|over 18/, // ...
  22. /beautyzone\.\w+|\.cam|lust\.\w+/i, // suspicious websites
  23. /-{5,}/, // too many "-"
  24. /SPECIAL FOR YOU|MY CONTENT|My mom.*subscribers|literally begging|MY VIDEOS|fucking cringe|Don'?t read my name/i, // common phrase
  25. (text) => {
  26. const charSets = [
  27. {
  28. regex: /[ᴀʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘᴏ̨ʀsᴛᴜᴠᴡxʏᴢ\s]/g,
  29. matchPercent: 0.5
  30. },
  31. {
  32. regex: /[\u{1D538}-\u{1D56B}]/gu, // math letter symbols
  33. matchPercent: 0.5
  34. },
  35. {
  36. regex: /[ㄥϛㄣƐᄅƖ⅄Λ∩┴ɹԀ˥ʞſפℲƎƆ∀ʎʍʌʇɹɯʞɾᴉɥƃɟǝɔɐ]/g,
  37. matchPercent: true
  38. }
  39. ];
  40. for (const check of charSets) {
  41. const { regex, matchPercent } = check,
  42. matches = text.match(regex)?.length ?? 0;
  43. if (matchPercent === true && matches) {
  44. console.log(matches)
  45. return true;
  46. }
  47. if (matches / text.length > matchPercent && text.length > 10) {
  48. console.log(matches, regex)
  49. return true;
  50. }
  51. }
  52. }
  53. ]
  54. }),
  55. site = getCurrentSite(),
  56. commentMutationListener = new MutationObserver((mutations) => {
  57. for (const mutation of mutations) {
  58. for (const node of mutation.addedNodes) {
  59. const text = getCommentText(node, site);
  60. if (text) {
  61. if (isCommentLikelyBotComment(text, site)) {
  62. node.style.display = "none";
  63. }
  64. }
  65. }
  66. }
  67. });
  68.  
  69. commentMutationListener.observe(document.body, {
  70. subtree: true,
  71. childList: true
  72. });
  73.  
  74. /**
  75. * Determines whether a comment is likely spam.
  76. *
  77. * @param {String} text The comment's content
  78. * @param {Object} site The website the comment is from
  79. * @return {Boolean}
  80. */
  81. function isCommentLikelyBotComment(text, siteChecks) {
  82. for (const check of siteChecks) {
  83. if (typeof check === "function") {
  84. if (check(text)) {
  85. return true;
  86. }
  87. } else {
  88. // assume regex
  89. if (check.test(text)) {
  90. return true;
  91. }
  92. }
  93. }
  94. return false;
  95. }
  96.  
  97. function getCommentText(node, site) {
  98. switch (site) {
  99. case SITES.YOUTUBE: {
  100. if (node.nodeName === "YTD-COMMENT-RENDERER") {
  101. return node.querySelector("#content-text").textContent;
  102. }
  103. }
  104. }
  105. return null;
  106. }
  107.  
  108. function getCurrentSite() {
  109. switch (location.hostname) {
  110. case "www.youtube.com": {
  111. return SITES.YOUTUBE;
  112. }
  113. }
  114. }