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

Python3.8调用Twitch API报400 Bad Request及KeyError错误求助

问题根源

你遇到的两个报错是递进关系:

  • Twitch API返回400错误Malformed query params是核心问题,这是本地参数错误导致,和Twitch API侧规则变动无关
  • KeyError: 'data'是因为请求失败时API返回结果没有data字段,你没有做错误校验直接读取字段导致的

具体错误点

  1. 参数带非法字符:用readlines()读取文件的每行内容时,会保留每行末尾的换行符\n,你把带换行符的主播名拼接到API请求URL中,导致user_login参数格式非法,触发Twitch的400错误
  2. 逻辑错误:check变量的判断逻辑错误,会导致你只会检测文档里的第一个主播,后续所有主播都不会触发检测流程
  3. 冗余请求:每次遍历主播都重新申请一次access_token,Twitch的client_credentials类型token有效期为4小时,频繁请求容易被接口限流
  4. 缺少错误校验:没有判断API请求是否成功就直接读取data字段,只要接口返回错误就会触发KeyError

修复方案

修正后的代码如下:

# 建议把token获取逻辑抽出来,全局只在token过期时刷新
access_token = None
client_id = 'k6hsyhu5xdr78uwtloku6slque6sxj'
client_secret = 'secret goes here'

def refresh_token():
    global access_token
    body = {
        'client_id': client_id,
        'client_secret': client_secret,
        "grant_type": 'client_credentials'
    }
    r = requests.post('https://id.twitch.tv/oauth2/token', body)
    keys = r.json()
    access_token = keys['access_token']

async def onlinecheck(onlines):
    # 首次运行或token过期时刷新token
    if not access_token:
        refresh_token()
    # 去掉错误的check变量判断
    with open('Twitch channels.txt', 'r', encoding='utf-8') as f:
        lines = f.readlines()
    for line in lines:
        line = line.strip() # 去掉首尾空白符、换行符
        if not line:
            continue
        entry = line.split(',')
        server = client.get_channel(int(entry[0]))
        channel = entry[1].strip() # 再单独对主播名去空白,避免前后有空格
        headers = {
            'Client-ID': client_id,
            'Authorization': 'Bearer ' + access_token
        }
        # 用params参数传查询条件,requests会自动做转义,避免特殊字符问题
        stream = requests.get(
            'https://api.twitch.tv/helix/streams',
            headers=headers,
            params={'user_login': channel}
        )
        # 先校验请求状态
        if stream.status_code != 200:
            # 401的情况大概率是token过期,刷新一次重试
            if stream.status_code == 401:
                refresh_token()
                continue
            # 其他错误直接跳过本次检测
            continue
        stream_data = stream.json()
        if len(stream_data.get('data', [])) == 1:
            if channel not in onlines:
                embed = discord.Embed(title=f"{channel} is streaming!",description=f"[link](https://www.twitch.tv/{channel})")
                await server.send(embed=embed)
                onlines.append(channel)
        else:
            if channel in onlines:
                onlines.remove(channel)
    await asyncio.sleep(240)

额外注意点

你原来的代码没有关闭文件的操作,修改后用with open语法会自动处理文件关闭,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:54:04