如何使用"不正确" python3中的JSON

时间:2018-03-27 12:17:29

标签: python json io python-3.5

我有一个JSON文件,格式如下 -

注意1和2之后的字符(等)表示没有双引号的字符串

{
    "Apparel": {
        "XX": {
            "1": YY,
            "2": ZZ
                },
        "TT": {
            "1":TTT,
            "2":TTT,
            "3": TTT,
            "4": TTT
                    },
        "XXX": {
            "1":XXX,
            "2":XXX
                    },
        "RRR": {
            "1":RRR,
            "2":RRR
                    },

        "AAA": {
            "1":AAA,
            "2":AAA,
            "3":AAA
                    },
                }
....

等等。

现在我知道文件没有正确格式化(由于设计或idk这样的文件保持这种方式)并且在Python3中使用它与标准的json模块会产生解码错误但是我已经被告知要按原样使用该文件。这意味着任何问题,我必须在我的代码中进行排序。我需要从每个标题中选择1后的值,然后从每个标题中选择2的值,依此类推。

目前我正在使用此代码来读取文件 -

import json

with open("brand_config.json") as json_file:
    json_data = json.load(json_file)
    test = (json_data["apparel"]["biba"])

print (test)

此代码提供此错误 -

Traceback (most recent call last):
  File "reader.py", line 4, in <module>
    json_data = json.load(json_file)
  File "/usr/lib/python3.5/json/__init__.py", line 268, in load
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
  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 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 4 column 9 (char 36)

如何在不更改JSON文件中的任何内容的情况下读取所需的值。

3 个答案:

答案 0 :(得分:1)

我从问题中了解到,您的JSON 的值未被引号包围。

我编写了以下脚本来解析问题中的特定文件

#!/usr/bin/env python3

from json import dumps


# Reads THAT SPECIFIC MALFORMATTED JSON, SHOULD NOT BE USED
def parse_json(filename):
    j = {}
    with open(filename, 'r') as json_file:
    lines = [line.strip() for line in json_file.readlines()]

    level = 0
    keys = []
    for line in lines:
        # increase a level
        if '{' in line:
            level += 1
            # append proper key
            if ':' in line:
                keys.append(line.split(':')[0].replace('"', '').strip())
                if level == 2:
                    j[keys[0]] = {}
                elif level == 3:
                    j[keys[0]][keys[1]] = {}
        # decrease a level, remove key
        elif '}' in line:
            keys = keys[:-1]
            level -= 1
        # add value
        else:
            if level == 3 and line:
                k, v = line.split(':')
                k = k.replace('"', '').strip()
                v = v.strip()[:-1]
                j[keys[0]][keys[1]][k] = v
    return j


brand_config = parse_json('brand_config.json')
print(dumps(brand_config, indent=4, sort_keys=True))

创建了一个python dictionary

{
    "Apparel": {
        "AAA": {
            "1": "AAA",
            "2": "AAA",
            "3": "AA"
        },
        "RRR": {
            "1": "RRR",
            "2": "RR"
        },
        "TT": {
            "1": "TTT",
            "2": "TTT",
            "3": "TTT",
            "4": "TT"
        },
        "XX": {
            "1": "YY",
            "2": "Z"
        },
        "XXX": {
            "1": "XXX",
            "2": "XX"
        }
    }
}

考虑到你在问题中提供的内容。

编辑:在评论中要求解释

keys是用于存储当前在json中使用的键的列表。例如,{ "Apparel": {}}表示keys=["Apparel"]{ "Apparel": {"AAA": XXX }}表示keys=["Apparel", "AAA"]

该函数一次处理一行文本文件

  • 创建一个空字典(j)。

  • 每当{时,级别增加1.如果行中存在:,请将其拆分并在删除引号后将第一个字符串用作dictionary key 。创建与该密钥关联的新词典。

  • 如果不存在{但是:,则拆分该行并将左侧值用作key,将右侧值用作value

  • 如果存在},请将级别降低1并删除最后一个键。

最后一行只是印刷它。

答案 1 :(得分:0)

你的json文件一定有问题。我不知道你从哪里得到这个文件,或者你自己生成了它。

你的命令是正确的,我做了相同的案例并且有效......

>>> import json
>>> obj = {5:'jul'}
>>> d = json.dump(obj,open(os.getcwd()+'/JS.sjon','w+'))
>>> ld = json.load(open(os.getcwd()+'/JS.sjon','r'))
{'5': 'jul'}
>>> ld.get('5')
'jul'

enter image description here

因此,请查看数据来源

答案 2 :(得分:0)

YAML是JSON的超集,在引用值时不那么严格(参见包pyaml)。

E.g。

import yaml

with open("brand_config.json") as json_file:
    json_data = yaml.safe_load(json_file)
    test = (json_data["apparel"]["biba"])

print (test)

我用你问题中的“坏”JSON片段尝试了这种方法,这就是我得到的:

{'Apparel': {'AAA': {'1': 'AAA', '2': 'AAA', '3': 'AAA'},
  'RRR': {'1': 'RRR', '2': 'RRR'},
  'TT': {'1': 'TTT', '2': 'TTT', '3': 'TTT', '4': 'TTT'},
  'XX': {'1': 'YY', '2': 'ZZ'},
  'XXX': {'1': 'XXX', '2': 'XXX'}}}