You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python新手开发Discord Bot遇编译错误,请求排查脚本交互缺陷

Discord Bot与查询脚本的问题分析与修复建议

核心问题梳理

你的代码存在多处逻辑错误和不规范写法,导致功能无法正常运行,甚至会破坏原脚本文件。以下是具体问题和修复方案:

Bot代码的明显错误与缺陷

  1. 错误的字符串替换逻辑
    你设置的STRING_TO_REPLACE = "addresses"会直接把查询脚本中的变量名addresses替换成用户输入的钱包地址,导致脚本变成类似["0x123..."] = ["WALLET_ADDRESS"]的非法代码,完全无法运行。正确做法是替换查询脚本中的WALLET_ADDRESS占位符,而非变量名。

  2. 永久修改原脚本文件
    每次运行命令都会直接覆盖查询脚本内容,多次执行后原脚本会彻底混乱。正确方式是通过命令行参数传递钱包地址给查询脚本,而非修改文件内容。

  3. 未处理命令参数缺失的情况
    如果用户只输入!run_script而没有跟上钱包地址,message.content.split()[1]会抛出索引越界异常,导致Bot崩溃。

  4. 未处理脚本运行异常
    subprocess.check_output会在脚本返回非零退出码时抛出异常,未捕获的话会导致Bot崩溃。同时,查询脚本中的input('Press ENTER to exit')会导致subprocess调用时卡住,因为没有交互输入通道。

  5. 无用的阻塞代码
    client.run(BOT_TOKEN)是阻塞调用,Bot运行后后面的input('Press ENTER to exit')永远不会执行,可直接删除。

查询脚本的问题

  1. 硬编码占位符且无参数接收逻辑
    脚本只能使用固定的WALLET_ADDRESS,无法通过外部参数接收地址,导致必须修改文件才能更换地址。

  2. 网络请求未处理异常
    requests.get没有处理超时、连接失败、HTTP错误码等情况,一旦请求失败会直接抛出异常终止脚本。

  3. 脆弱的JSON解析逻辑
    使用list(a1['contacts'].keys())[0]这种方式获取键值非常脆弱,若返回的JSON结构变化会直接报错。同时捕获所有except:会掩盖真正的错误原因,不利于调试。

  4. 多余的阻塞输入
    input('Press ENTER to exit')在被subprocess调用时会导致脚本卡住,无法正常输出结果并退出。

优化后的完整代码示例

改进后的Bot代码

import discord
import subprocess
from discord.ext import commands

# 替换为你的Bot令牌
BOT_TOKEN = "TOKEN_VALUE"
# 查询脚本的路径
SCRIPT_PATH = "query_script.py"

# 使用commands框架更方便处理命令参数
bot = commands.Bot(command_prefix="!", intents=discord.Intents.default())

@bot.event
async def on_ready():
    print(f"已登录为 {bot.user.name}")

@bot.command(name="run_script")
async def run_script(ctx, wallet_address: str):
    try:
        # 通过命令行参数传递钱包地址给查询脚本,避免修改原文件
        result = subprocess.run(
            ["python", SCRIPT_PATH, wallet_address],
            capture_output=True,
            text=True,
            timeout=10  # 设置超时,防止脚本卡住
        )
        # 合并标准输出和标准错误
        output = result.stdout + result.stderr
        await ctx.send(f"脚本输出:\n```\n{output}\n```")
    except subprocess.TimeoutExpired:
        await ctx.send("脚本运行超时,请稍后重试")
    except Exception as e:
        await ctx.send(f"运行脚本时出错: {str(e)}")

bot.run(BOT_TOKEN)

改进后的查询脚本(重命名为query_script.py)

import requests
import json
import sys

def resolve_wallet(address):
    url = f"https://meta-api.reddit.com/crypto-contacts?providers=ethereum&addresses={address}"
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()  # 触发HTTP错误码的异常
        data = response.json()
        
        contacts = data.get('contacts', {})
        if not contacts:
            return f"{address} 未找到关联用户,可能不是有效地址"
        
        # 遍历所有联系人(处理多个结果的情况)
        for addr_info in contacts.values():
            if addr_info and 'username' in addr_info[0]:
                return f"{address} 关联用户: u/{addr_info[0]['username']}"
        return f"{address} 未找到有效用户名"
    except requests.exceptions.RequestException as e:
        return f"{address} 请求失败: {str(e)}"
    except (KeyError, IndexError) as e:
        return f"{address} 解析失败: 数据格式异常"

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("请提供钱包地址作为命令行参数")
        sys.exit(1)
    wallet_addr = sys.argv[1]
    print(resolve_wallet(wallet_addr))

关键优化点说明

  • 采用discord.ext.commands框架处理命令,自动解析参数并处理错误,比原生on_message更简洁可靠。
  • 通过命令行参数传递钱包地址,彻底避免修改原脚本文件的风险。
  • 为网络请求和脚本运行添加超时限制,防止无限阻塞。
  • 具体捕获特定异常,便于排查问题,同时避免掩盖未知错误。
  • 移除了所有会导致阻塞的input()调用,确保脚本能被subprocess正常调用并返回结果。

内容的提问来源于stack exchange,提问作者Tom Hutchison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:55:05