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

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

目前為 2025-02-11 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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 });
    */
})();