You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用json.loads解析嵌套JSON失败的解决方法咨询

解决嵌套字符串化JSON的解析问题

我明白你遇到的问题了——Redis里存的这个字符串其实是Python字典的字符串表示(用单引号),而不是标准JSON,而且里面还嵌套了一个标准JSON格式的optional_parameters字段,直接用json.loads()肯定会报错,因为JSON规范要求用双引号包裹键和字符串。

下面是两种可靠的解决方法,优先推荐第一种:

方法1:用ast.literal_eval先转成Python字典,再解析嵌套字段

ast.literal_eval可以安全地解析Python的字面量(包括单引号的字典),不会像eval()那样有安全风险。拿到字典后,再把optional_parameters里的字符串JSON解析成字典即可。

修改你的代码如下:

import ast
import json

async for value in RedisHandler.get_all_keys():
    examined_counter += 1
    task = None
    try:
        # 第一步:把单引号的Python字典字符串转成真实的Python字典
        task_dict = ast.literal_eval(value)
        
        # 第二步:遍历tasklist,解析每个item里的optional_parameters
        for task_item in task_dict.get('tasklist', []):
            opt_params_str = task_item.get('optional_parameters')
            if isinstance(opt_params_str, str):
                try:
                    task_item['optional_parameters'] = json.loads(opt_params_str)
                except json.JSONDecodeError as e:
                    logger.warning(f"Failed parsing optional_parameters for task {task_item['opuid']}: {str(e)}. Keeping original string.")
        
        # 现在task_dict就是包含完整嵌套结构的字典了,你可以直接使用,或者转成标准JSON
        task = task_dict
        # 如果需要标准JSON字符串:task_json = json.dumps(task_dict)
    except Exception as convertException:
        logger.info(f"Failed converting value into valid structure: {str(convertException)}. Skipping.")
        continue

为什么这个方法可靠?

  • ast.literal_eval会正确处理字符串内部的单引号(如果存在的话),不会像盲目的replace("'", '"')那样破坏嵌套的JSON字符串。
  • 分步解析能精准处理嵌套的JSON字段,同时保留错误处理逻辑,避免单个字段解析失败导致整个任务被跳过。

方法2:修复字符串格式后再解析(不推荐,容易踩坑)

如果你不想用ast模块,可以尝试先把外层的单引号替换成双引号,但要注意不要替换optional_parameters里面的双引号。不过这种方法只适用于你的字符串里没有其他单引号的情况,比如字符串值里不含单引号:

async for value in RedisHandler.get_all_keys():
    examined_counter += 1
    task = None
    try:
        # 先把外层的单引号替换成双引号,注意:如果字符串值里有单引号会出错!
        fixed_value = value.replace("'", '"')
        task = json.loads(fixed_value)
        # 此时optional_parameters已经是字符串,再解析一次
        for task_item in task.get('tasklist', []):
            if isinstance(task_item['optional_parameters'], str):
                task_item['optional_parameters'] = json.loads(task_item['optional_parameters'])
    except Exception as convertException:
        logger.info("Failed converting '%s' into JSON. Skipping." % value)
        continue

注意事项

这个方法的风险很高——如果你的字典里任何字符串值包含单引号(比如description字段是"don't do this"),替换后会变成"don"t do this",直接导致JSON解析失败。所以优先用方法1。


内容的提问来源于stack exchange,提问作者Ali Yılmaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:20:25