为什么python不能解析这个json数据?

Why can't Python parse this JSON data?

我在一个文件中有这个JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
   "maps": [
        {
           "id":"blabla",
           "iscategorical":"0"
        },
        {
           "id":"blabla",
           "iscategorical":"0"
        }
    ],
   "masks": [
       "id":"valore"
    ],
   "om_points":"value",
   "parameters": [
       "id":"valore"
    ]
}

我编写了这个脚本来打印所有的JSON数据:

1
2
3
4
5
6
7
import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

不过,此程序引发了一个异常:

1
2
3
4
5
6
7
8
9
10
Traceback (most recent call last):
  File"<pyshell#1>", line 5, in <module>
    data = json.load(f)
  File"/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File"/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File"/usr/lib/python3.5/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 13 column 13 (char 213)

如何解析JSON并提取其值?


您的数据不是有效的JSON格式。你有[],而你应该有{}

  • []用于json数组,在python中称为list
  • {}用于json对象,在python中称为dict

以下是JSON文件的外观:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
   "maps": [
        {
           "id":"blabla",
           "iscategorical":"0"
        },
        {
           "id":"blabla",
           "iscategorical":"0"
        }
    ],
   "masks": {
       "id":"valore"
    },
   "om_points":"value",
   "parameters": {
       "id":"valore"
    }
}

然后您可以使用您的代码:

1
2
3
4
5
6
7
import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

通过数据,您现在还可以找到这样的值:

1
2
3
data["maps"][0]["id"]
data["masks"]["id"]
data["om_points"]

试一试,看看是否有意义。


您的data.json应该如下所示:

1
2
3
4
5
{
"maps":[
         {"id":"blabla","iscategorical":"0
<div class="
suo-content">[collapse title=""]<ul><li>我对此投了反对票。也许还不清楚,为什么我认为需要另一个答案。添加了关于WITH语句兼容性的说明。</li><li>很抱歉回滚,但建议的代码将使<wyn>data_file</wyn><wyn>open</wyn>的运行时间比需要的时间长。</li><li>参考2.6文档(docs.python.org/2.6/library/io.html),在"with"上下文中打开文件将自动关闭文件。</li><li>史蒂夫。是的,但不是在离开上下文之前。在<wyn>with</wyn>的上下文中,<wyn>pprint</wyn>ing使<wyn>data_file</wyn>打开的时间更长。</li><li>是否有访问方式,如data.om_points或data.masks.id?</li><li>这是有效的,除非当我尝试使用像<wyn>data["maps"][0]["id"]</wyn>这样的编号索引时,我看到错误:<wyn>KeyError: 0</wyn>。</li><li>@gayanpathirage您可以像访问<wyn>data["om_points"]</wyn>,<wyn>data["masks"]["id"]</wyn>一样访问它。其思想是,通过指定"键路径",可以达到字典中的任何级别。如果您得到一个<wyn>KeyError</wyn>异常,这意味着路径中不存在密钥。注意打字错误或查字典的结构。</li></ul>[/collapse]</div><p><center>[wp_ad_camp_1]</center></p><hr><P>Justin Peel的答案非常有用,但是如果您使用的是python 3,那么应该这样做:</P>[cc lang="python"]with open('data.json', encoding='utf-8') as data_file:
    data = json.loads(data_file.read())

注:用json.loads代替json.load。在python 3中,json.loads接受一个字符串参数。json.load采用类似文件的对象参数。data_file.read()返回一个字符串对象。


1
2
3
4
data = []
with codecs.open('d:\output.txt','rU','utf-8') as f:
    for line in f:
       data.append(json.loads(line))


"ultra-json"或简单的"ujson"可以处理json文件输入中的[]。如果您正在将JSON输入文件作为JSON元素列表读取到程序中,例如,[{[{}]}, {}, [], etc...]ujson可以处理任意顺序的字典列表、列表字典。

您可以在python包索引中找到ujson,该API几乎与python的内置json库相同。

如果加载更大的JSON文件,UJSON也更快。与提供的同一链接中的其他python json库相比,您可以看到性能详细信息。


如果使用python3,可以尝试将(connection.json文件)json更改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
 "connection1": {
   "DSN":"con1",
   "UID":"abc",
   "PWD":"1234",
   "connection_string_python":"test1"
  }
  ,
 "connection2": {
   "DSN":"con2",
   "UID":"def",
   "PWD":"1234"
  }
}

然后使用以下代码:

1
2
3
4
5
connection_file = open('connection.json', 'r')
conn_string = json.load(connection_file)
conn_string['connection1']['connection_string_python'])
connection_file.close()
>>> test1


这里是修改后的data.json文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
   "maps": [
        {
           "id":"blabla",
           "iscategorical":"0"
        },
        {
           "id":"blabla",
           "iscategorical":"0"
        }
    ],
   "masks": [{
       "id":"valore"
    }],
   "om_points":"value",
   "parameters": [{
       "id":"valore"
    }]
}

您可以使用以下行在控制台上调用或打印数据:

1
2
3
4
5
import json
from pprint import pprint
with open('data.json') as data_file:
    data_item = json.load(data_file)
pprint(data_item)

print(data_item['parameters'][0]['id'])的预期产量:

1
2
3
4
5
{'maps': [{'id': 'blabla', 'iscategorical': '0'},
          {'id': 'blabla', 'iscategorical': '0'}],
 'masks': [{'id': 'valore'}],
 'om_points': 'value',
 'parameters': [{'id': 'valore'}]}

print(data_item['parameters'][0]['id'])的预期产量:

1
valore


作为python3用户,

loadloads方法之间的区别非常重要,特别是当您从文件中读取JSON数据时。

如文件所述:

JSON.Load:

Deserialize fp (a .read()-supporting text file or binary
file containing a JSON document) to a Python object using this
conversion table.

负载:

json.loads: Deserialize s (a str, bytes or bytearray instance
containing a JSON document) to a Python object using this conversion
table.

加载方法可以直接读取打开的JSON文档,因为它可以读取二进制文件。

1
2
with open('./recipes.json') as data:
  all_recipes = json.load(data)

因此,您的JSON数据以根据此转换表指定的格式提供:

https://docs.python.org/3.7/library/json.html json到py表


此分析中有两种类型。

  • 从系统路径分析文件中的数据
  • 从远程URL解析JSON。
  • 从文件中,可以使用以下内容

    1
    2
    3
    4
    import json
    json = json.loads(open('/path/to/file.json').read())
    value = json['key']
    print json['value']

    这个Arcticle解释了使用两个场景进行完整的解析和获取值。