DeepSeek 自动重试 & 点击次数上限

当页面中出现“服务器繁忙,请稍后再试”的提示时,自动点击 id 为“重新生成”的元素进行重试。页面右下角显示一个大盒子,包含自动重试开关及点击次数上限设置(含当前计数显示),点击次数达到上限时自动关闭重试。适用于 deepseek 页面。

目前为 2025-02-15 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name DeepSeek 自动重试 & 点击次数上限
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.7
  5. // @description 当页面中出现“服务器繁忙,请稍后再试”的提示时,自动点击 id 为“重新生成”的元素进行重试。页面右下角显示一个大盒子,包含自动重试开关及点击次数上限设置(含当前计数显示),点击次数达到上限时自动关闭重试。适用于 deepseek 页面。
  6. // @author Loki2077
  7. // @match https://chat.deepseek.com/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // 自动重试是否启用,默认开启
  16. let autoRetryEnabled = true;
  17. // 记录当前自动点击重试的次数
  18. let retryClickCount = 0;
  19. // 定义间隔时间变量(单位:秒)
  20. let jgtime = 30;
  21. // 定义倒计时变量
  22. let countdown = jgtime;
  23.  
  24. // 创建 UI 大盒子,包含开关按钮和点击次数上限设置
  25. function createUIBox() {
  26. const container = document.createElement('div');
  27. container.id = 'auto-retry-box';
  28. container.style.position = 'fixed';
  29. container.style.bottom = '10px';
  30. container.style.right = '10px';
  31. container.style.zIndex = 9999;
  32. container.style.background = 'rgba(0, 0, 0, 0.7)';
  33. container.style.color = '#fff';
  34. container.style.padding = '10px';
  35. container.style.borderRadius = '5px';
  36. container.style.fontSize = '14px';
  37.  
  38. // 开关按钮
  39. const toggleBtn = document.createElement('button');
  40. toggleBtn.id = 'auto-retry-toggle';
  41. toggleBtn.style.width = '100%';
  42. toggleBtn.style.padding = '8px';
  43. toggleBtn.style.backgroundColor = '#007BFF';
  44. toggleBtn.style.color = '#FFFFFF';
  45. toggleBtn.style.border = 'none';
  46. toggleBtn.style.borderRadius = '5px';
  47. toggleBtn.style.cursor = 'pointer';
  48. toggleBtn.textContent = autoRetryEnabled ? '关闭自动重试' : '开启自动重试';
  49.  
  50. toggleBtn.addEventListener('click', () => {
  51. autoRetryEnabled = !autoRetryEnabled;
  52. toggleBtn.textContent = autoRetryEnabled ? '关闭自动重试' : '开启自动重试';
  53. countdown = autoRetryEnabled ? jgtime : '关闭';
  54. console.log(`自动重试功能已${autoRetryEnabled ? '开启' : '关闭'}`);
  55. });
  56.  
  57. container.appendChild(toggleBtn);
  58.  
  59. // 点击次数上限和当前计数显示
  60. const limitBox = document.createElement('div');
  61. limitBox.style.marginTop = '10px';
  62.  
  63. const limitLabel = document.createElement('label');
  64. limitLabel.htmlFor = 'max-click-input';
  65. limitLabel.textContent = '点击次数上限: ';
  66.  
  67. const maxClickInput = document.createElement('input');
  68. maxClickInput.id = 'max-click-input';
  69. maxClickInput.type = 'number';
  70. maxClickInput.value = '5';
  71. maxClickInput.min = '0';
  72. maxClickInput.style.width = '50px';
  73. maxClickInput.style.marginRight = '10px';
  74.  
  75. // 当前点击次数显示
  76. const countDisplay = document.createElement('span');
  77. countDisplay.id = 'click-count';
  78. countDisplay.textContent = retryClickCount;
  79.  
  80. // 组合 limitBox
  81. limitBox.appendChild(limitLabel);
  82. limitBox.appendChild(maxClickInput);
  83. limitBox.appendChild(document.createTextNode(' 当前点击次数: '));
  84. limitBox.appendChild(countDisplay);
  85.  
  86. container.appendChild(limitBox);
  87.  
  88. // 间隔时间设置
  89. const intervalBox = document.createElement('div');
  90. intervalBox.style.marginTop = '10px';
  91.  
  92. const intervalLabel = document.createElement('label');
  93. intervalLabel.htmlFor = 'interval-input';
  94. intervalLabel.textContent = '间隔时间 (秒): ';
  95.  
  96. const intervalInput = document.createElement('input');
  97. intervalInput.id = 'interval-input';
  98. intervalInput.type = 'number';
  99. intervalInput.value = jgtime;
  100. intervalInput.min = '1';
  101. intervalInput.style.width = '80px';
  102. intervalInput.style.marginRight = '10px';
  103.  
  104. intervalInput.addEventListener('change', () => {
  105. jgtime = Number(intervalInput.value) || 30;
  106. countdown = jgtime;
  107. clearInterval(checkInterval);
  108. checkInterval = setInterval(checkAndRetry, jgtime * 1000);
  109. console.log(`间隔时间已修改为 ${jgtime} 秒`);
  110. });
  111.  
  112. const countdownDisplay = document.createElement('span');
  113. countdownDisplay.id = 'countdown-display';
  114. countdownDisplay.textContent = `倒计时: ${countdown} 秒`;
  115.  
  116. intervalBox.appendChild(intervalLabel);
  117. intervalBox.appendChild(intervalInput);
  118. intervalBox.appendChild(countdownDisplay);
  119.  
  120. container.appendChild(intervalBox);
  121.  
  122. document.body.appendChild(container);
  123. }
  124.  
  125. // 检查页面是否出现错误提示,并执行自动重试操作(带点击次数上限判断)
  126. function checkAndRetry() {
  127. if (!autoRetryEnabled) return;
  128.  
  129. // 获取用户设置的最大点击次数(转为数字)
  130. const maxClickInput = document.getElementById('max-click-input');
  131. const maxClickCount = Number(maxClickInput.value) || 0;
  132.  
  133. // 如果已达到或超过点击次数上限,则关闭自动重试功能
  134. if (retryClickCount >= maxClickCount && maxClickCount > 0) {
  135. console.log("已达到点击次数上限,自动重试功能自动关闭。");
  136. autoRetryEnabled = false;
  137. // 更新开关按钮显示
  138. document.getElementById('auto-retry-toggle').textContent = '开启自动重试';
  139. return;
  140. }
  141.  
  142. // 查询包含错误提示的元素(例如:<div class="ds-markdown ds-markdown--block"><p>服务器繁忙,请稍后再试。</p></div>)
  143. const errorParagraphs = document.querySelectorAll('.ds-markdown.ds-markdown--block p');
  144. for (let i = 0; i < errorParagraphs.length; i++) {
  145. if (errorParagraphs[i].innerText.indexOf("服务器繁忙,请稍后再试") !== -1) {
  146. console.log("检测到服务器繁忙提示,尝试自动重新生成...");
  147.  
  148. const retryElement = document.getElementById("重新生成");
  149. if (retryElement) {
  150. console.log("找到 id 为 '重新生成' 的元素,正在触发点击事件...");
  151. // 使用 click() 或手动派发事件兼容 SVG 元素
  152. if (typeof retryElement.click === "function") {
  153. retryElement.click();
  154. } else {
  155. const event = new MouseEvent("click", {
  156. view: window,
  157. bubbles: true,
  158. cancelable: true
  159. });
  160. retryElement.dispatchEvent(event);
  161. }
  162. // 增加点击计数,并更新 UI 显示
  163. retryClickCount++;
  164. document.getElementById('click-count').textContent = retryClickCount;
  165. } else {
  166. console.log("未找到 id 为 '重新生成' 的元素,请检查页面结构是否有变化。");
  167. }
  168. // 检测到一次错误提示后退出循环
  169. break;
  170. }
  171. }
  172. }
  173.  
  174. // 初始化 UI
  175. createUIBox();
  176.  
  177. // 每隔 jgtime 秒检测页面内容
  178. let checkInterval = setInterval(checkAndRetry, jgtime * 1000);
  179.  
  180. // 更新倒计时显示
  181. setInterval(() => {
  182. // 如果启用了自动重试功能,并且倒计时减到 0,就重置倒计时
  183. if (countdown === 0 && autoRetryEnabled) {
  184. countdown = jgtime;
  185. }
  186. // 如果倒计时大于 0 并且自动重试功能开启,则继续倒计时
  187. if (countdown > 0 && autoRetryEnabled) {
  188. countdown--;
  189. } else {
  190. countdown = "关闭";
  191. }
  192. // 更新倒计时显示
  193. if (countdown === "关闭") {
  194. document.getElementById('countdown-display').textContent = ` ${countdown} `;
  195. }else{
  196. document.getElementById('countdown-display').textContent = `倒计时: ${countdown} 秒`;
  197. }
  198. }, 1000);
  199.  
  200. // 如有需要,可以使用 MutationObserver 监听 DOM 变化(可选)
  201. /*
  202. const observer = new MutationObserver(checkAndRetry);
  203. observer.observe(document.body, { childList: true, subtree: true });
  204. */
  205. })();

QingJ © 2025

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