如何安全访问嵌套 JSON 数据并避免 KeyError 异常
发布时间 - 2026-01-11 00:00:00 点击率:次本文讲解如何在 python 中安全访问 api 返回的嵌套 json 字段(如 `normaltime`、`period1` 等),通过 `.get()` 方法优雅处理缺失键,防止 `keyerror` 中断程序,并提供默认值(如 `999`)或合理回退逻辑。
在调用 SofaScore 等第三方体育 API 时,常见问题之一是:部分比赛数据尚未生成(例如未开赛或已取消),导致 homeScore 或 awayScore 对象中缺少 normaltime、period1 等字段。直接使用 game['homeScore']['normaltime'] 会触发 KeyError: 'normaltime',程序立即崩溃。
根本原因在于——Python 字典的方括号语法 d[key] 要求键必须存在,否则抛出异常;而更健壮的做法是使用 .get(key, default) 方法:它在键不存在时返回 None(或你指定的默认值),而非报错。
以下为优化后的核心实践:
✅ 正确做法:逐层使用 .get() 安全取值
对任意可能缺失的嵌套层级(如 game → homeScore → normaltime),均应链式调用 .get(),并设置合理默认值。例如:
homescore = game.get("homeScore", {}).get("normaltime", 999)
awayscore = game.get("awayScore", {}).get("normaltime", 999)
homehalf = game.get("homeScore", {}).get("period1", 0) # 上半场比分默认为 0
awayhalf = game.get("awayScore", {}).get("period1", 0)⚠️ 注意命名冲突:避免覆盖内置函数
原代码中使用 round = game['roundInfo']['round'] 将变量命名为 round,这会覆盖 Python 内置函数 round(),可能导致后续数值四舍五入等操作异常。应改用 game_round 或 round_name 等语义化名称。
✅ 安全提取赛事轮次信息(含多级 fallback)
roundInfo 本身也可能为空,因此需先检查其存在性,再取子字段:
round_info = game.get("roundInfo")
if round_info:
round_name = round_info.get("name") or f"Round {round_info.get('round', '?')}"
else:
round_name = "Not Scheduled"? 完整修复示例(含时间格式化与错误兜底):
from datetime import datetime
import requests
import json
url = "https://api.sofascore.com/api/v1/sport/football/scheduled-events/2025-02-01"
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"origin": "https://www.sofascore.com",
"referer": "https://www.sofascore.com/",
}
response = requests.get(url, headers=headers)
jsondata = response.json()
for game in jsondata.get("events", []):
try:
league = game.get("tournament", {}).get("name", "Unknown League")
hometeam = game.get("homeTeam", {}).get("name", "N/A")
awayteam = game.get("awayTeam", {}).get("name", "N/A")
# 安全获取比分(缺失时返回 999)
homescore = game.get("homeScore", {}).get("normaltime", 999)
awayscore = game.get("awayScore", {}).get("normaltime", 999)
homehalf = game.get("homeScore", {}).get("period1", 0)
awayhalf = game.get("awayScore", {}).get("period1", 0)
# 安全获取开始时间
timestamp = game.ge
t("startTimestamp")
time_str = datetime.fromtimestamp(timestamp).strftime("%H:%M") if timestamp else "TBD"
# 安全获取轮次
round_info = game.get("roundInfo", {})
round_name = round_info.get("name") or f"Round {round_info.get('round', '?')}"
print(f"{league} | {hometeam} - {awayteam} ({homehalf}-{awayhalf}) {homescore}-{awayscore} | {time_str} | {round_name}")
except Exception as e:
print(f"[Warning] Failed to parse game: {e}")
continue? 关键总结:
- ✅ 永远对第三方 API 响应做防御性编程:假设任何字段都可能缺失;
- ✅ 优先使用 .get(key, default) 替代 ['key'];
- ✅ 对嵌套结构(如 game['homeScore']['normaltime'])务必分步 .get(),并在中间层提供空字典 {} 作为 fallback;
- ✅ 避免使用 round、list、str 等内置名作变量;
- ✅ 添加 try...except 包裹单条记录解析,确保一条失败不影响整体流程。
这样即可稳定运行,无论数据是否完整。
# python
# js
# json
# windows
# app
# ai
# win
# apple
# 常见问题
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何正确选择百度移动适配建站域名?
Laravel如何实现用户密码重置功能?(完整流程代码)
如何快速启动建站代理加盟业务?
JS去除重复并统计数量的实现方法
Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】
jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】
,交易猫的商品怎么发布到网站上去?
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
高防服务器如何保障网站安全无虞?
深圳网站制作平台,深圳市做网站好的公司有哪些?
php json中文编码为null的解决办法
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
香港服务器如何优化才能显著提升网站加载速度?
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
长沙做网站要多少钱,长沙国安网络怎么样?
音乐网站服务器如何优化API响应速度?
如何快速生成ASP一键建站模板并优化安全性?
如何在腾讯云免费申请建站?
LinuxShell函数封装方法_脚本复用设计思路【教程】
活动邀请函制作网站有哪些,活动邀请函文案?
如何快速搭建高效WAP手机网站吸引移动用户?
如何用AWS免费套餐快速搭建高效网站?
python中快速进行多个字符替换的方法小结
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
SQL查询语句优化的实用方法总结
Python自动化办公教程_ExcelWordPDF批量处理案例
Laravel怎么清理缓存_Laravel optimize clear命令详解
Python函数文档自动校验_规范解析【教程】
Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区
PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑
Bootstrap CSS布局之列表
使用Dockerfile构建java web环境
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
如何快速重置建站主机并恢复默认配置?
Linux系统命令中tree命令详解
如何快速搭建高效香港服务器网站?
Laravel如何配置任务调度?(Cron Job示例)
javascript如何操作浏览器历史记录_怎样实现无刷新导航
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
phpredis提高消息队列的实时性方法(推荐)
如何用美橙互联一键搭建多站合一网站?
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
Android利用动画实现背景逐渐变暗
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
java获取注册ip实例
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
Laravel如何使用Vite进行前端资源打包?(配置示例)
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
nodejs redis 发布订阅机制封装实现方法及实例代码


t("startTimestamp")
time_str = datetime.fromtimestamp(timestamp).strftime("%H:%M") if timestamp else "TBD"
# 安全获取轮次
round_info = game.get("roundInfo", {})
round_name = round_info.get("name") or f"Round {round_info.get('round', '?')}"
print(f"{league} | {hometeam} - {awayteam} ({homehalf}-{awayhalf}) {homescore}-{awayscore} | {time_str} | {round_name}")
except Exception as e:
print(f"[Warning] Failed to parse game: {e}")
continue