Python3.8调用Twitch API报400 Bad Request及KeyError错误求助
问题根源
你遇到的两个报错是递进关系:
- Twitch API返回400错误
Malformed query params是核心问题,这是本地参数错误导致,和Twitch API侧规则变动无关 KeyError: 'data'是因为请求失败时API返回结果没有data字段,你没有做错误校验直接读取字段导致的
具体错误点
- 参数带非法字符:用
readlines()读取文件的每行内容时,会保留每行末尾的换行符\n,你把带换行符的主播名拼接到API请求URL中,导致user_login参数格式非法,触发Twitch的400错误 - 逻辑错误:
check变量的判断逻辑错误,会导致你只会检测文档里的第一个主播,后续所有主播都不会触发检测流程 - 冗余请求:每次遍历主播都重新申请一次access_token,Twitch的client_credentials类型token有效期为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
相关产品推荐
相关产品推荐

