谷歌自动翻译特定次数

将输入的文本翻译成随机语言,可以指定随机次数

  1. // ==UserScript==
  2. // @name 谷歌自动翻译特定次数
  3. // @namespace moe001,hcl67
  4. // @version 1.02
  5. // @description 将输入的文本翻译成随机语言,可以指定随机次数
  6. // @author moe001,hcl67
  7. // @match *://translate.google.com/
  8. // @match *://translate.google.com.hk/
  9. // @match *://translate.google.*/
  10. // @grant none
  11. // @license MIT
  12. // 基于moe001 v1.01脚本,更新swapButton
  13.  
  14. // ==/UserScript==
  15. var sleep = (time) => { return new Promise((resolve) => setTimeout(resolve, time)) }
  16.  
  17.  
  18. // 在网页右下角创建一个控制面板
  19. var panel = document.createElement('div');
  20. panel.style.position = 'fixed';
  21. panel.style.bottom = '0';
  22. panel.style.right = '0';
  23. panel.style.width = '300px';
  24. panel.style.height = '300px';
  25. panel.style.backgroundColor = 'rgba(0,0,0,0.2)';
  26. panel.style.color = 'white';
  27. panel.style.zIndex = '9999';
  28. panel.style.padding = '10px';
  29. panel.style.boxSizing = 'border-box';
  30. panel.style.borderRadius = '10px';
  31. document.body.appendChild(panel);
  32. // 面板里第一行是输入框,用来输入次数,默认值为20,不可为负数
  33. var input = document.createElement('input');
  34. input.style.width = '100%';
  35. input.style.boxSizing = 'border-box';
  36. input.style.marginBottom = '10px';
  37. input.value = '20';
  38. panel.appendChild(input);
  39. // 面板里第二行是按钮,点击后开始翻译
  40. var button = document.createElement('button');
  41. button.style.width = '100%';
  42. button.style.boxSizing = 'border-box';
  43. button.style.marginBottom = '10px';
  44. button.innerText = '开始翻译';
  45. panel.appendChild(button);
  46. // 面板里第三行是一个多行文本框,不能输入,作为日志栏展示操作进度,大小不可变
  47. var log = document.createElement('textarea');
  48. log.style.width = '100%';
  49. log.style.height = '75%';
  50. log.style.boxSizing = 'border-box';
  51. log.style.marginBottom = '10px';
  52. log.readOnly = true;
  53. log.style.resize = 'none';
  54. // 上边缘外侧有一个折叠按钮,点击后折叠面板
  55. var foldButton = document.createElement('button');
  56. foldButton.style.position = 'absolute';
  57. foldButton.style.top = '-30px';
  58. foldButton.style.right = '0';
  59. foldButton.style.width = '30px';
  60. foldButton.style.height = '30px';
  61. foldButton.style.backgroundColor = 'rgba(0,0,0,0.2)';
  62. foldButton.style.color = '#333';
  63. foldButton.style.zIndex = '9999';
  64. foldButton.style.borderRadius = '10px';
  65. foldButton.innerText = '↓';
  66. foldButton.addEventListener('click', () => {
  67. if (panel.style.height == '300px') {
  68. panel.style.height = '0px';
  69. foldButton.innerText = '↑';
  70. } else {
  71. panel.style.height = '300px';
  72. foldButton.innerText = '↓';
  73. }
  74. });
  75. panel.appendChild(foldButton);
  76. panel.appendChild(log);
  77. // 添加日志的方法
  78. var addLog = (text,br = true) => {
  79. log.value += text;
  80. if(br) log.value += '\n';
  81. log.scrollTop = log.scrollHeight;
  82. }
  83. // 清空日志的方法
  84. var clearLog = () => {
  85. log.value = '';
  86. }
  87.  
  88.  
  89. // 语言互换的按钮路径为.aCQag > c-wiz:nth-child(1) > div:nth-child(1) > c-wiz:nth-child(1) > div:nth-child(3) > div:nth-child(1) > span:nth-child(1) > button:nth-child(1)
  90. // var swapButton = document.querySelector('.aCQag > c-wiz:nth-child(1) > div:nth-child(1) > c-wiz:nth-child(1) > div:nth-child(3) > div:nth-child(1) > span:nth-child(1) > button:nth-child(1)');
  91. var swapButton = document.querySelector('.dig2sb > span > .lRTpdf.ZihNHd.mN1ivc.eT1oJ.yHy1rc.VfPpkd-Bz112c-LgbsSe-OWXEXe-e5LLRc-SxQuSe.VfPpkd-Bz112c-LgbsSe > .VfPpkd-Bz112c-RLmnJb')
  92.  
  93. // 目标语言按钮 按属性查找jsname="zumM6d"
  94. var targetLanguageButton = document.querySelector('[jsname="zumM6d"]');
  95. // 查找所有语言的按钮,语言按钮是一个div,一定有data-language-code属性,并且都在一个div里,这个div有属性jsname="gnoFo",然后中间还有一层div是jsname="Kxj0sc"
  96. var languageButtons = document.querySelector('[jsname="gnoFo"]').querySelector('[jsname="Kxj0sc"]').querySelectorAll('[data-language-code]');
  97.  
  98.  
  99.  
  100. var waitForSwapButtonDisabled = () => {
  101. return new Promise((resolve) => {
  102. var observer = new MutationObserver((mutationsList) => {
  103. for (var mutation of mutationsList) {
  104. if (mutation.type == 'attributes') {
  105. if (mutation.attributeName == 'disabled') {
  106. resolve();
  107. observer.disconnect();
  108. }
  109. }
  110. }
  111. });
  112. observer.observe(swapButton, { attributes: true });
  113. });
  114. }
  115.  
  116. var waitForSwapButtonEnabled = () => {
  117. return new Promise((resolve) => {
  118. var observer = new MutationObserver((mutationsList) => {
  119. for (var mutation of mutationsList) {
  120. if (mutation.type == 'attributes') {
  121. if (mutation.attributeName == 'disabled') {
  122. resolve();
  123. observer.disconnect();
  124. }
  125. }
  126. }
  127. });
  128. observer.observe(swapButton, { attributes: true });
  129. });
  130. }
  131. var waitForSwapButton = () => {
  132. waitForSwapButtonDisabled();
  133. waitForSwapButtonEnabled();
  134. }
  135.  
  136. // 当开始翻译按钮被点击时 调用一个异步函数
  137. button.addEventListener('click', async () => {
  138. // 获取输入框的值
  139. var count = input.value;
  140. // 如果输入的值不是数字或者小于等于0,提示错误并退出
  141. if (isNaN(count) || count <= 0) {
  142. alert('请输入大于0的数字');
  143. return;
  144. }
  145. // 将输入框设为不可用
  146. input.disabled = true;
  147. // 将开始翻译按钮设为不可用
  148. button.disabled = true;
  149. // 将日志栏清空
  150. clearLog();
  151. // 设置来源语言为自动
  152. addLog('设置来源语言为自动');
  153. // 自动来源语言按钮 按属性查找
  154. var autoSourceLanguageButton = document.querySelector('[jsname="gnoFo"]').querySelector('[data-language-code="auto"]');
  155. autoSourceLanguageButton.click();
  156. // 等待切换按钮的属性变化
  157. waitForSwapButton();
  158. await sleep(1000);
  159. // 将日志栏添加一条信息
  160. addLog('开始翻译' + count + '次');
  161. while (count > 0) {
  162. // 随机选择一个目标语言
  163. var lastLanguage = "";
  164. var targetLanguage = languageButtons[Math.floor(Math.random() * languageButtons.length)];
  165. // 如果随机到的目标语言和当前语言一样,重新随机
  166. // 语言名为里面第二个div
  167. var targetLanguageName = targetLanguage.children[1].innerText;
  168. while (targetLanguageName == lastLanguage) {
  169. targetLanguage = languageButtons[Math.floor(Math.random() * languageButtons.length)];
  170. targetLanguageName = targetLanguage.children[1].innerText;
  171. }
  172. lastLanguage = targetLanguageName;
  173. // 将日志栏添加一条信息
  174. addLog('目标语言:' + targetLanguageName);
  175. // 点击目标语言按钮
  176. targetLanguage.click();
  177. addLog('处理中');
  178. // 等待切换按钮的属性变化
  179. waitForSwapButton();
  180. // 等待1秒
  181. await sleep(1000);
  182. // 点击语言互换按钮
  183. swapButton.click();
  184. addLog('更新原文');
  185. // 等待切换按钮的属性变化
  186. waitForSwapButton();
  187.  
  188. await sleep(500);
  189. // 翻译次数减一
  190. count--;
  191. addLog('剩余' + count + '次');
  192. addLog('----------------');
  193. }
  194. // 译回中文
  195. addLog('译回中文');
  196. // 找到中文按钮
  197. var chineseButton = document.querySelector('[jsname="gnoFo"]').querySelector('[jsname="Kxj0sc"]').querySelector('[data-language-code="zh-CN"]');
  198. // 点击中文按钮
  199. chineseButton.click();
  200. // 等待切换按钮的属性变化
  201. waitForSwapButton();
  202. // 等待1秒
  203. await sleep(1000);
  204. // 恢复输入框的可用状态
  205. input.disabled = false;
  206. // 恢复开始翻译按钮的可用状态
  207. button.disabled = false;
  208. // 将日志栏添加一条信息
  209. addLog('翻译完成');
  210.  
  211. });

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址