解析嵌套的JSON数据

9

这是一个来自MongoDB聚合查询的JSON输出。我需要将嵌套数据JSON解析为以下格式,即'total''_id'值。

{
'ok': 1.0, 
'result': [
            {
                'total': 142250.0, 
                '_id': 'BC'
            }, 
            {
                'total': 210.88999999999996,
                 '_id': 'USD'
            }, 

            {
                'total': 1065600.0, 
                '_id': 'TK'
            }
            ]
}

我已经尝试了5种不同的技术来获取我需要的内容,但是在使用jsonsimplejson模块时遇到了问题。

理想情况下,输出应该像这样:

142250.0, BC
210.88999999999996, USD
1065600.0, TK

你能否发布一下你使用这两个模块尝试的代码? - ely
正如cpburnz的回答中所提到的:问题在于单引号和双引号字符。您需要使用双引号,然后简单调用json.loads即可解决(在进行此更改后,您的JSON字符串可以成功加载并且易于解析)。 - ely
5个回答

15

注意:来自 MongoDB 的 JSON 响应实际上是无效的。JSON 要求使用双引号 ("),而不是单引号 (')。

我不确定为什么你的响应中有单引号而不是双引号,但从外观上看,你可以将它们替换为双引号,然后只需使用内置的 json 模块:

from __future__ import print_function
import json

response = """{
    'ok': 1.0, 
    'result': [
        {
            'total': 142250.0, 
            '_id': 'BC'
        }, 
        {
            'total': 210.88999999999996,
             '_id': 'USD'
        }, 

        {
            'total': 1065600.0, 
            '_id': 'TK'
        }
        ]
}"""

# JSON requires double-quotes, not single-quotes.
response = response.replace("'", '"')
response = json.loads(response)
for doc in response['result']:
    print(doc['_id'], doc['total'])

1
我认为你的意思是在注释行中json需要双引号。 - ely
1
是的,我写反了。已修复。 - Uyghur Lives Matter
我没有意识到你正在进行编辑。我注意到在我修复各种错别字后,有些东西消失了几次,所以我重新编辑以恢复消失的内容(可能是由于冲突的编辑引起的?) - Uyghur Lives Matter
不要对带有结构化数据的字符串(例如Python字典的文字)使用无条件替换。这可能会在一段时间内起作用,直到它悄悄地破坏其中的数据。而应该使用适当的解析器,例如ast.literal_eval() - jfs
@J.F. 好的,ast.literal_eval() 是更安全的解决方案(从MongoDB获得正确响应是最好的)。鉴于数据仅包含货币代码字符串和数字值,搜索和替换就足够了。这将错误地将嵌入的 \' 转换为 \"(例如,that\'s 将变成 that\"s)。严谨地说,如果响应包含 DateObjectIdliteral_eval() 将失败。但如果它们不需要,那么这仍然可能更好。 - Uyghur Lives Matter
显示剩余2条评论

0

从mongodb获取的响应似乎与字典类型对象兼容。

{
    'ok': 1.0,  'result': [
        {
            'total': 142250.0, 
            '_id': 'BC'
        }, 
        {
            'total': 210.88999999999996,
             '_id': 'USD'
        }, 
        {
            'total': 1065600.0, 
            '_id': 'TK'
        }
    ]
}

我们可不可以直接将其分配给字典类型对象,然后像这样执行进一步的操作,而不是将其放入多行字符串并将单引号替换为双引号:

json_data = {
    'ok': 1.0,
    'result':
        [
            {
                'total': 142250.0,
                '_id': 'BC'
            },
            {
                'total': 210.88999999999996,
                '_id': 'USD'
            },
            {
                'total': 1065600.0,
                '_id': 'TK'
            }
    ]
}

并且:

for data in json_data['result']:
    print(data['total'], data['_id'])

-1
import json

data = json.loads(mongo_db_json)
result = data['result']
for value_dict in result:
    print '{0}, {1}'.format(value['total'], value['_id'])

这应该可以工作


实际上,楼主说他尝试了5种不同的方法,没有提到任何具体的方法。但也可以理解,这可能并不是一件简单的事情。 - elssar
是的,这个方法不起作用,原因在第一个答案中提到。PyMongo在输出中只使用单引号。 - unique_beast

-1

你的示例文本不是有效的JSON文本。JSON字符串必须以"引号开头,而不是';但它似乎是一个有效的Python文字,你可以使用ast.literal_eval()函数进行解析:

import ast

data = ast.literal_eval(input_string)
for item in data["result"]:
    print("{total}, {_id}".format(**item))

输出

142250.0, BC
210.89, USD
1065600.0, TK

一种更好的方法可能是修复查询过程以获取有效的JSON,并使用json模块对其进行解析。

所有的值都是单引号响应。 - unique_beast
data = ast.literal_eval(str(response)) for item in data["result"]: print("{total}, {_id}".format(**item))
- unique_beast
现在暂时只能这样了,虽然我想从我的Mongo实例中获取JSON... - unique_beast
1
@EMS:我在问题中没有看到JSON数据。因此,我不使用JSON解析器来解析它。我已经编辑了答案,明确提到输入应更改为JSON。 - jfs
@EMS:如果输入是JSON,则可以使用json模块。故事结束了。但是,如果输入不是JSON,并且OP无法/不愿修复类似Python文字的输入,则ast.literal_eval比盲目的.replace更安全,正如我已经评论过的那样(https://dev59.com/Q3jZa4cB1Zd3GeqPgqgu#19730573?noredirect=1#comment29314372_19729976)。 - jfs
显示剩余3条评论

-2

这应该可以。

import json

def parse_json(your_json):
    to_dict = json.loads(your_json)
    for item in to_dict['results']:
        print item['total']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接