如何安全访问嵌套 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.get("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 发布订阅机制封装实现方法及实例代码