如何自动解析JSON并提取所有底层键值对存入变量?
核心实现思路
通过递归函数遍历所有嵌套层级,不需要预先知道JSON的结构,自动提取所有最底层的键值对,同时支持配置排除/包含规则过滤不需要的内容。
实现代码
基础版(仅处理字典嵌套,支持排除键)
def flatten_dict(nested_dict, exclude_keys=None, keep_full_path=False): exclude_keys = exclude_keys or [] result = {} def _traverse(current_data, path_prefix=""): if isinstance(current_data, dict): for k, v in current_data.items(): # 跳过指定要排除的键 if k in exclude_keys: continue current_path = f"{path_prefix}_{k}" if path_prefix else k _traverse(v, current_path) else: # 到达非字典类型的底层值,存入结果 final_key = path_prefix if keep_full_path else path_prefix.split("_")[-1] result[final_key] = current_data _traverse(nested_dict) return result
使用示例
你只需要传入Response["Response"]节点作为遍历起点,同时配置要排除的键即可:
# 假设API响应存放在api_response变量中 target_node = api_response["Response"] # 定义要排除的不需要的键 exclude_list = ["privacy", "seasonHashes"] # 自动展平得到所有底层键值对 flat_data = flatten_dict(target_node, exclude_keys=exclude_list)
最终得到的flat_data就是你需要的结构,例如:
{ "crossSaveOverride": 1, "applicableMembershipTypes": [3, 1], "isPublic": True, "membershipType": 1, "membershipId": "123", "displayName": "Name1", "bungieGlobalDisplayName": "name again", "bungieGlobalDisplayNameCode": 0000, "dateLastPlayed": "2021-6-18T02:33:01Z", "versionsOwned": 127, "characterIds": ["id1", "id2", "id3"], "currentSeasonHash": 3434243244, "currentSeasonRewardPowerCap": 1330 }
你可以直接把这个字典的键作为数据库列名,值作为对应字段内容批量入库,不需要硬编码任何层级路径。
功能扩展
1. 白名单模式(仅保留指定键)
如果只需要特定的几个字段,可以修改函数增加白名单参数,过滤掉不在白名单内的所有内容:
def flatten_dict(nested_dict, exclude_keys=None, include_keys=None, keep_full_path=False): exclude_keys = exclude_keys or [] include_keys = include_keys or [] result = {} def _traverse(current_data, path_prefix=""): if isinstance(current_data, dict): for k, v in current_data.items(): if k in exclude_keys: continue current_path = f"{path_prefix}_{k}" if path_prefix else k _traverse(v, current_path) else: final_key = path_prefix if keep_full_path else path_prefix.split("_")[-1] # 开启白名单后仅保留指定键 if include_keys and final_key not in include_keys: return result[final_key] = current_data _traverse(nested_dict) return result
使用时传入你需要的字段即可,比如仅保留displayName和isPublic:
flat_data = flatten_dict(target_node, include_keys=["displayName", "isPublic"])
得到的结果就和你给出的示例结构完全一致。
2. 处理列表嵌套字典的场景
如果你的API响应中存在列表嵌套字典的结构,可以扩展递归逻辑支持列表遍历:
def _traverse(current_data, path_prefix=""): if isinstance(current_data, dict): for k, v in current_data.items(): if k in exclude_keys: continue current_path = f"{path_prefix}_{k}" if path_prefix else k _traverse(v, current_path) elif isinstance(current_data, list): for index, item in enumerate(current_data): current_path = f"{path_prefix}_{index}" if path_prefix else str(index) _traverse(item, current_path) else: final_key = path_prefix if keep_full_path else path_prefix.split("_")[-1] if include_keys and final_key not in include_keys: return result[final_key] = current_data
3. 重名键处理
如果不同层级存在同名的键,可以将keep_full_path参数设置为True,最终得到的键会携带完整层级路径(例如profile_data_userInfo_displayName),避免字段覆盖。
内容的提问来源于stack exchange,提问作者dekubaka
相关产品推荐
相关产品推荐

