【问题标题】:Parse JSON with single, double quotes and unicode with python 2.7 [duplicate]使用 python 2.7 解析带有单引号、双引号和 unicode 的 JSON [重复]
【发布时间】:2019-12-26 23:23:46
【问题描述】:

TL:DR:我正在尝试使用 curl 传递 JSON 内容并失败了。

我有一个包含以下内容的文件:

test_api.txt 内容:

data={"crt":"t45","res_type":1,"stype":"standard","config":"{u'global': {u'lang': [], u'floor': u'1', u'tmax': 1000, u'dsp': [{u'status': u'disable', u'id': u'92'}], u'request_at': 3, u'crt_list': [{u'width': u'25', u'height': u'50', u'stype': u'restype', u'format': u'restype'}], u'request': True, u'geo': [{u'geo_id': u'21', u'floor': u'50'}]}}","sl_org":555,"parse_to":1111,"group_id":2020,"name":"test_api"}

据我了解,数据的值是有效的json,因为所有在线验证器都同意它是有效的。实际上这是 python 的json.dumps() 的结果。

我是这样发送的:

curl -v -X POST 'https://example.com/api/v2/entity/create' -H "Content-Type: application/x-www-form-urlencoded" -d  "@test_api.txt"

如果我打印 POST 内容,我会看到什么:

<QueryDict: {u'data': [u'{"crt":"t45","res_type":1,"stype":"standard","config":"{u\'global\': {u\'lang\': [], u\'floor\': u\'1\', u\'tmax\': 1000, u\'dsp\': [{u\'status\': u\'disable\', u\'id\': u\'92\'}], u\'request_at\': 3, u\'crt_list\': [{u\'width\': u\'25\', u\'height\': u\'50\', u\'stype\': u\'restype\', u\'format\': u\'restype\'}], u\'request\': True, u\'geo\': [{u\'geo_id\': u\'21\', u\'floor\': u\'50\'}]}}","sl_org":555,"parse_to":1111,"group_id":2020,"name":"test_api"}']}>

接下来我用 json.loads() 解析该代码,然后得到以下 dict:

{u'stype': u'standard', u'config': u"{u'global': {u'lang': [], u'floor': u'1', u'tmax': 1000, u'dsp': [{u'status': u'disable', u'id': u'92'}], u'request_at': 3, u'crt_list': [{u'width': u'25', u'height': u'50', u'stype': u'restype', u'format': u'restype'}], u'request': True, u'geo': [{u'geo_id': u'21', u'floor': u'50'}]}}", u'name': u'test_api', u'parse_to': 1111, u'res_type': 1, u'crt': u't45', u'sl_org': 555, u'group_id': 2020}

现在我必须解析这个 dict 中 'config' 键的值,它实际上包含一个带有另一个 JSON 字段的字符串:

value = u"{u'global': {u'lang': [], u'floor': u'1', u'tmax': 1000, u'dsp': [{u'status': u'disable', u'id': u'92'}], u'request_at': 3, u'crt_list': [{u'width': u'25', u'height': u'50', u'stype': u'restype', u'format': u'restype'}], u'request': True, u'geo': [{u'geo_id': u'21', u'floor': u'50'}]}}"

这就是问题所在:任何尝试使用带有json.loads(value) 的json 解析此字符串的尝试都将失败:

"ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"

是的,它在双引号内有单引号,它看起来不正确,但我得到的这个字符串默认为json.loads(),正如你所看到的,这就是 python 的作用。

我的问题是 - 出了什么问题以及如何解决?我通过标准的对称 python 函数传递有效的 json 并得到损坏的 json 结果。如何修复此管道并正确获取此 json 解析?

【问题讨论】:

  • 你的内容不是 JSON{u'global': ...} 是 Python 序列化,而不是 JSON 序列化。
  • 你可以用ast.literal_eval()解析它。

标签: python json


【解决方案1】:

你的外部结构是 JSON,但内部内容不是 JSON,而是 Python 字面量;因此,您需要为此使用 Python 语法感知工具,而不是 JSON 工具。

import json, ast

json_str = '''{"crt":"t45","res_type":1,"stype":"standard","config":"{u'global': {u'lang': [], u'floor': u'1', u'tmax': 1000, u'dsp': [{u'status': u'disable', u'id': u'92'}], u'request_at': 3, u'crt_list': [{u'width': u'25', u'height': u'50', u'stype': u'restype', u'format': u'restype'}], u'request': True, u'geo': [{u'geo_id': u'21', u'floor': u'50'}]}}","sl_org":555,"parse_to":1111,"group_id":2020,"name":"test_api"}'''
data = json.loads(json_str)
config = ast.literal_eval(data['config'])

print(config['global']['tmax']) # emits 1000

【讨论】:

  • 嗯,我很确定内部 'json' 是 json.dumps(value) 的结果,它实际上是一个表单字段被转储。请让我检查一下。
  • 看起来你是对的,它只是一个字符串。非常感谢!
猜你喜欢
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 2018-09-05
  • 2012-10-16
  • 1970-01-01
相关资源
最近更新 更多