如何在Python中解析API返回的嵌套JSON并获取指定嵌套值
嘿,这个需求我经常遇到,给你分享几种简单又实用的实现方式,让你能像访问对象属性那样轻松操作返回的JSON数据!
方法一:用Python内置的types.SimpleNamespace(推荐)
Python 3.3+自带了SimpleNamespace,可以快速把字典转换成可点访问的对象。我们只需要写一个递归函数,处理嵌套的字典和列表结构:
import requests import os from types import SimpleNamespace def dict_to_obj(d): # 递归处理嵌套字典 if isinstance(d, dict): return SimpleNamespace(**{k: dict_to_obj(v) for k, v in d.items()}) elif isinstance(d, list): # 处理列表里的元素(如果有嵌套字典的话) return [dict_to_obj(item) for item in d] else: # 非字典/列表类型直接返回 return d # 你的原有调用API代码 file_name = os.path.join('/home/pp2018/public/users/roger123/000000000285.jpg') files = {'file': open(file_name, 'rb')} url = "http://111.111.111.111:57149" res = requests.post(url, files=files) data_dict = res.json() # 把字典转换成可点访问的对象 data_obj = dict_to_obj(data_dict) # 现在就能像你想要的那样访问啦! print(data_obj.pic2.Pos[0]) # 输出 99.99
这个方法的好处是用内置模块,不需要额外装第三方库,而且递归处理能覆盖所有嵌套场景,不管你的JSON有多复杂都能搞定。
方法二:自定义一个JSON转换类
如果你想更灵活地控制转换逻辑,可以自己写一个简单的类,利用__dict__来绑定属性:
import requests import os class JSONObject: def __init__(self, data): # 遍历字典,把键值对转成属性 for key, value in data.items(): if isinstance(value, dict): # 嵌套字典继续转成JSONObject setattr(self, key, JSONObject(value)) elif isinstance(value, list): # 列表里的字典也处理 setattr(self, key, [JSONObject(item) if isinstance(item, dict) else item for item in value]) else: # 普通值直接赋值 setattr(self, key, value) # 原有API调用代码不变 file_name = os.path.join('/home/pp2018/public/users/roger123/000000000285.jpg') files = {'file': open(file_name, 'rb')} url = "http://111.111.111.111:57149" res = requests.post(url, files=files) data_dict = res.json() data_obj = JSONObject(data_dict) print(data_obj.pic2.Pos[0]) # 输出 99.99
这种方式适合后续需要扩展功能的场景,比如加一些属性验证或者自定义处理逻辑。
方法三:解析JSON时直接指定转换钩子
还可以在解析JSON字符串的时候,用json.loads的object_hook参数直接完成转换,一步到位:
import requests import os import json from types import SimpleNamespace def dict_to_obj(d): if isinstance(d, dict): return SimpleNamespace(**{k: dict_to_obj(v) for k, v in d.items()}) elif isinstance(d, list): return [dict_to_obj(item) for item in d] else: return d # 原有API调用代码 file_name = os.path.join('/home/pp2018/public/users/roger123/000000000285.jpg') files = {'file': open(file_name, 'rb')} url = "http://111.111.111.111:57149" res = requests.post(url, files=files) # 解析时直接转换 data_obj = json.loads(res.text, object_hook=dict_to_obj) print(data_obj.pic2.Pos[0]) # 输出 99.99
这个方法省去了先转成字典再转换的步骤,效率稍微高一点,逻辑也很清晰。
以上几种方法都能满足你的需求,我个人最推荐第一种,因为简洁、可靠,还不用额外依赖~
内容的提问来源于stack exchange,提问作者Willie Cheng
相关产品推荐
相关产品推荐

