Python解码JSON中的嵌套JSON

2024-05-19 01:48:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理一个API,不幸的是它返回了格式错误的JSON(或者“奇怪的格式”,更确切地说——谢谢@fjarri),但从积极的方面来说,我认为这可能是我学习递归和JSON的一个机会。这是一个应用程序,我用来记录我的训练,我试图做一个备份脚本。

我可以接收JSON fine,但即使在requests.get(api_url).json()(或json.loads(requests.get(api_url).text))之后,其中一个值仍然是JSON编码的字符串。幸运的是,我只需json.loads()字符串,它就可以正确地解码为dict。特定的键是可预测的:timezone_id,而它的值是不同的(因为数据已经记录在多个时区中)。例如,解码后,可能是:dump"timezone_id": {\"name\":\"America/Denver\",\"seconds\":\"-21600\"}"的形式归档,或者load'timezone_id': '{"name":"America/Denver","seconds":"-21600"}'的形式导入Python

问题是,我使用这个API来检索相当数量的数据,这些数据有几层dict和list,并且双编码的timezone_id在多个级别出现。

这是我到目前为止的一些示例数据的工作,但似乎我离基础还很远。

#! /usr/bin/env python3

import json
from pprint import pprint

my_input = r"""{
    "hasMore": false,
    "checkins": [
        {
            "timestamp": 1353193745000,
            "timezone_id": "{\"name\":\"America/Denver\",\"seconds\":\"-21600\"}",
            "privacy_groups": [
                "private"
            ],
            "meta": {
                "client_version": "3.0",
                "uuid": "fake_UUID"
            },
            "client_id": "fake_client_id",
            "workout_name": "Workout (Nov 17, 2012)",
            "fitness_workout_json": {
                "exercise_logs": [
                    {
                        "timestamp": 1353195716000,
                        "type": "exercise_log",
                        "timezone_id": "{\"name\":\"America/Denver\",\"seconds\":\"-21600\"}",
                        "workout_log_uuid": "fake_UUID"
                    },
                    {
                        "timestamp": 1353195340000,
                        "type": "exercise_log",
                        "timezone_id": "{\"name\":\"America/Denver\",\"seconds\":\"-21600\"}",
                        "workout_log_uuid": "fake_UUID"
                    }
                ]
            },
            "workout_uuid": ""
        },
        {
            "timestamp": 1354485615000,
            "user_id": "fake_ID",
            "timezone_id": "{\"name\":\"America/Denver\",\"seconds\":\"-21600\"}",
            "privacy_groups": [
                "private"
            ],
            "meta": {
                "uuid": "fake_UUID"
            },
            "created": 1372023457376,
            "workout_name": "Workout (Dec 02, 2012)",
            "fitness_workout_json": {
                "exercise_logs": [
                    {
                        "timestamp": 1354485615000,
                        "timezone_id": "{\"name\":\"America/Denver\",\"seconds\":\"-21600\"}",
                        "workout_log_uuid": "fake_UUID"
                    },
                    {
                        "timestamp": 1354485584000,
                        "timezone_id": "{\"name\":\"America/Denver\",\"seconds\":\"-21600\"}",
                        "workout_log_uuid": "fake_UUID"
                    }
                ]
            },
            "workout_uuid": ""
        }]}"""

def recurse(obj):
    if isinstance(obj, list):
        for item in obj:
            return recurse(item)
    if isinstance(obj, dict):
        for k, v in obj.items():
            if isinstance(v, str):
                try:
                    v = json.loads(v)
                except ValueError:
                    pass
                obj.update({k: v})
            elif isinstance(v, (dict, list)):
                return recurse(v)

pprint(json.loads(my_input, object_hook=recurse))

有什么好的方法来json.loads()所有这些双重编码的值而不改变对象的其余部分的建议吗?多谢提前!

这篇文章似乎是一个很好的参考:Modifying Deeply-Nested Structures

编辑:这被标记为可能重复的of this question——我认为这是完全不同的,因为我已经演示了使用json.loads()不起作用。这个解决方案最终需要一个object_hook,我在解码json时从未使用过它,在前面的问题中没有提到。


Tags: namelogidjsonobjuuidtimestampfake

热门问题