Streamlit运行时调用requests响应json()方法报错如何解决
报错核心原因
执行r.json()触发报错的直接原因是:后端接口返回的响应内容不是合法JSON格式,同时你的代码存在两个明显逻辑缺陷,会直接触发或放大异常:
- 没有做HTTP状态码校验:只要后端返回404、500、403这类错误,响应内容一般是HTML格式的错误页,根本不是JSON,直接调用
r.json()必然抛出解析异常 - 变量作用域错误:
res是按钮点击后才会赋值的变量,你把if res['code'] == 200的判断写在了if Predict:代码块外面,页面首次加载没点按钮时,res根本不存在,也会直接抛错 - 附带一个业务逻辑bug:判断乘客不满意时加载
Happy.jpg、满意时加载NotHappy.jpg,对应关系写反了
排查步骤
按顺序查就能定位根因:
- 在
r = requests.post(URL, json=data)下一行加st.write("响应状态码:", r.status_code, "响应原始内容:", r.text),先看接口实际返回了什么 - 如果状态码不是200:依次检查后端服务是否正常启动、接口URL是否拼写正确、传入的
data参数格式是否符合接口要求、是否缺少接口要求的鉴权头/Content-Type头 - 如果状态码是200但返回内容不是JSON:检查后端接口代码,看是否在返回JSON前输出了调试打印、报错提示等额外内容,破坏了JSON结构
修复后的完整代码
替换原有代码即可,已经加了全链路异常捕获、修正了作用域问题和图片对应逻辑:
import requests import streamlit as st if st.button('Predict Satisfacion Rate'): try: # 发请求加10秒超时,避免页面无限卡死 r = requests.post(URL, json=data, timeout=10) # 先校验HTTP层状态,4xx/5xx直接抛请求异常 r.raise_for_status() # 尝试解析JSON res = r.json() if res.get('code') == 200: satisfaction = res['result']['description'] if satisfaction == 'Not Satisfied': st.markdown('**The Passenger is not Satisfied**') _, mid_col, _ = st.columns([1,1,1]) with mid_col: st.image('NotHappy.jpg') else: st.markdown('**The Passenger is Satisfied**') _, mid_col, _ = st.columns([1,1,1]) with mid_col: st.image('Happy.jpg') else: st.error('业务处理失败') err_msg = res.get('result', {}).get('description', '无有效错误信息') st.write(f"错误详情:{err_msg}") except requests.exceptions.RequestException as e: st.error('接口请求失败') st.write(f"请求错误:{str(e)}") except ValueError: st.error('响应解析失败,后端未返回合法JSON') st.write(f"后端原始返回:{r.text}") except Exception as e: st.error('程序运行异常') st.write(f"错误详情:{str(e)}")
编码注意事项
- Streamlit是从上到下重跑的执行逻辑,所有依赖按钮/交互组件触发才生成的变量,相关处理逻辑必须全部写在对应的组件判断缩进块内,不要写到块外,否则会出现变量未定义的报错
- 调用外部接口永远不要假设接口一定正常返回,必须加异常捕获和超时设置
- 取嵌套字典字段尽量用
get()方法,避免字段缺失直接触发KeyError中断页面渲染
内容的提问来源于stack exchange,提问作者sildaf88
相关产品推荐
相关产品推荐

