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

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

当前为 2025-02-11 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         DeepSeek 自动重试 & 点击次数上限
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  当页面中出现“服务器繁忙,请稍后再试”的提示时,自动点击 id 为“重新生成”的元素进行重试。页面右下角显示一个大盒子,包含自动重试开关及点击次数上限设置(含当前计数显示),点击次数达到上限时自动关闭重试。适用于 deepseek 页面。
// @author       Loki2077
// @match        https://chat.deepseek.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 自动重试是否启用,默认开启
    let autoRetryEnabled = true;
    // 记录当前自动点击重试的次数
    let retryClickCount = 0;
    // 定义间隔时间变量(单位:秒)
    let jgtime = 30;
    // 定义倒计时变量
    let countdown = jgtime;

    // 创建 UI 大盒子,包含开关按钮和点击次数上限设置
    function createUIBox() {
        const container = document.createElement('div');
        container.id = 'auto-retry-box';
        container.style.position = 'fixed';
        container.style.bottom = '10px';
        container.style.right = '10px';
        container.style.zIndex = 9999;
        container.style.background = 'rgba(0, 0, 0, 0.7)';
        container.style.color = '#fff';
        container.style.padding = '10px';
        container.style.borderRadius = '5px';
        container.style.fontSize = '14px';

        // 开关按钮
        const toggleBtn = document.createElement('button');
        toggleBtn.id = 'auto-retry-toggle';
        toggleBtn.style.width = '100%';
        toggleBtn.style.padding = '8px';
        toggleBtn.style.backgroundColor = '#007BFF';
        toggleBtn.style.color = '#FFFFFF';
        toggleBtn.style.border = 'none';
        toggleBtn.style.borderRadius = '5px';
        toggleBtn.style.cursor = 'pointer';
        toggleBtn.textContent = autoRetryEnabled ? '关闭自动重试' : '开启自动重试';

        toggleBtn.addEventListener('click', () => {
            autoRetryEnabled = !autoRetryEnabled;
            toggleBtn.textContent = autoRetryEnabled ? '关闭自动重试' : '开启自动重试';
            countdown = autoRetryEnabled ? jgtime : '关闭';
            console.log(`自动重试功能已${autoRetryEnabled ? '开启' : '关闭'}`);
        });

        container.appendChild(toggleBtn);

        // 点击次数上限和当前计数显示
        const limitBox = document.createElement('div');
        limitBox.style.marginTop = '10px';

        const limitLabel = document.createElement('label');
        limitLabel.htmlFor = 'max-click-input';
        limitLabel.textContent = '点击次数上限: ';

        const maxClickInput = document.createElement('input');
        maxClickInput.id = 'max-click-input';
        maxClickInput.type = 'number';
        maxClickInput.value = '5';
        maxClickInput.min = '0';
        maxClickInput.style.width = '50px';
        maxClickInput.style.marginRight = '10px';

        // 当前点击次数显示
        const countDisplay = document.createElement('span');
        countDisplay.id = 'click-count';
        countDisplay.textContent = retryClickCount;

        // 组合 limitBox
        limitBox.appendChild(limitLabel);
        limitBox.appendChild(maxClickInput);
        limitBox.appendChild(document.createTextNode(' 当前点击次数: '));
        limitBox.appendChild(countDisplay);

        container.appendChild(limitBox);

        // 间隔时间设置
        const intervalBox = document.createElement('div');
        intervalBox.style.marginTop = '10px';

        const intervalLabel = document.createElement('label');
        intervalLabel.htmlFor = 'interval-input';
        intervalLabel.textContent = '间隔时间 (秒): ';

        const intervalInput = document.createElement('input');
        intervalInput.id = 'interval-input';
        intervalInput.type = 'number';
        intervalInput.value = jgtime;
        intervalInput.min = '1';
        intervalInput.style.width = '80px';
        intervalInput.style.marginRight = '10px';

        intervalInput.addEventListener('change', () => {
            jgtime = Number(intervalInput.value) || 30;
            countdown = jgtime;
            clearInterval(checkInterval);
            checkInterval = setInterval(checkAndRetry, jgtime * 1000);
            console.log(`间隔时间已修改为 ${jgtime} 秒`);
        });

        const countdownDisplay = document.createElement('span');
        countdownDisplay.id = 'countdown-display';
        countdownDisplay.textContent = `倒计时: ${countdown} 秒`;

        intervalBox.appendChild(intervalLabel);
        intervalBox.appendChild(intervalInput);
        intervalBox.appendChild(countdownDisplay);

        container.appendChild(intervalBox);

        document.body.appendChild(container);
    }

    // 检查页面是否出现错误提示,并执行自动重试操作(带点击次数上限判断)
    function checkAndRetry() {
        if (!autoRetryEnabled) return;

        // 获取用户设置的最大点击次数(转为数字)
        const maxClickInput = document.getElementById('max-click-input');
        const maxClickCount = Number(maxClickInput.value) || 0;

        // 如果已达到或超过点击次数上限,则关闭自动重试功能
        if (retryClickCount >= maxClickCount && maxClickCount > 0) {
            console.log("已达到点击次数上限,自动重试功能自动关闭。");
            autoRetryEnabled = false;
            // 更新开关按钮显示
            document.getElementById('auto-retry-toggle').textContent = '开启自动重试';
            return;
        }

        // 查询包含错误提示的元素(例如:<div class="ds-markdown ds-markdown--block"><p>服务器繁忙,请稍后再试。</p></div>)
        const errorParagraphs = document.querySelectorAll('.ds-markdown.ds-markdown--block p');
        for (let i = 0; i < errorParagraphs.length; i++) {
            if (errorParagraphs[i].innerText.indexOf("服务器繁忙,请稍后再试") !== -1) {
                console.log("检测到服务器繁忙提示,尝试自动重新生成...");

                const retryElement = document.getElementById("重新生成");
                if (retryElement) {
                    console.log("找到 id 为 '重新生成' 的元素,正在触发点击事件...");
                    // 使用 click() 或手动派发事件兼容 SVG 元素
                    if (typeof retryElement.click === "function") {
                        retryElement.click();
                    } else {
                        const event = new MouseEvent("click", {
                            view: window,
                            bubbles: true,
                            cancelable: true
                        });
                        retryElement.dispatchEvent(event);
                    }
                    // 增加点击计数,并更新 UI 显示
                    retryClickCount++;
                    document.getElementById('click-count').textContent = retryClickCount;
                } else {
                    console.log("未找到 id 为 '重新生成' 的元素,请检查页面结构是否有变化。");
                }
                // 检测到一次错误提示后退出循环
                break;
            }
        }
    }

    // 初始化 UI
    createUIBox();

    // 每隔 jgtime 秒检测页面内容
    let checkInterval = setInterval(checkAndRetry, jgtime * 1000);

    // 更新倒计时显示
    setInterval(() => {
        if (countdown > 0 && autoRetryEnabled) {
            countdown--;
        } else {
            countdown = "关闭";
        }
        if (countdown === "关闭") {
            document.getElementById('countdown-display').textContent = ` ${countdown} `;
        }else{
            document.getElementById('countdown-display').textContent = `倒计时: ${countdown} 秒`;
        }
    }, 1000);

    // 如有需要,可以使用 MutationObserver 监听 DOM 变化(可选)
    /*
    const observer = new MutationObserver(checkAndRetry);
    observer.observe(document.body, { childList: true, subtree: true });
    */
})();