Python json.loads无法解析json字符串

时间:2016-05-23 09:20:03

标签: python json

我正在处理一个辅助项目,并且无法让json模块解析我存储在文本文件中的json对象。文本文件包含换行符分隔的json对象列表。

到目前为止,我已经确认这个代码正在检索每个完整的json行,然后将其提供给json.loads()

def load_save_game(file_name):
    save_game = []
    with open(file_name) as f:
        for line in f.readline():
            save_game.append(json.loads(line))
    return save_game

当我运行这个时,我会得到一个相当长的回溯:

Traceback (most recent call last):
  File ____, line 70, in <module> 
    main()
  File ____, line 66, in main
    view = ViewerWindow(load_save_game('played/20_05_2016 16-04-31.txt'))
  File ____, line 60, in load_save_game
    save_game.append(json.loads(line))
  File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Python27\lib\json\decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting object: line 1 column 1 (char 0)

我怀疑问题可能与编码有关,但在调查此事后,我发现JSON库可以挑剔诸如真值的大写,悬空逗号和单引号等内容而非双重引号。

Python 2.7似乎使用json的RFC 7159 and ECMA 404规范,所以我使用免费的在线json validator来查看json是否形成错误。它已经成功验证了json的所有标准,因此python应该对输入非常满意。

我托管了json on pastebin的一行,唯一的区别是the file中有没有空格,我也上传了。

我在线寻找解决方案并尝试了一些不同的解决方案,例如大写真值,替换所有单引号,以及解码ascii中的文本。

2 个答案:

答案 0 :(得分:3)

您正在循环第一行的字符

for line in f.readline():

f.readline()返回一个字符串,即文件的第一行。你根本不需要在这里调用readline(),只需直接迭代文件对象:

with open(file_name) as f:
    for line in f:
        if line.strip():
            save_game.append(json.loads(line))

我在额外测试中添加了跳过空行(文件末尾可以轻松包含一行)。

您也可以将上述内容转换为列表理解:

def load_save_game(file_name):
    with open(file_name) as f:
        return [json.loads(l) for l in f if l.strip()]

请注意,如果您的JSON文档本身不包含换行符,则上述仅适用。如果文件中只有一个JSON文档,请使用json.load(f)(无循环),或使用different technique解析文档中新行的多个JSON文档。

上述方法适用于您提供的示例文件,无论是否有line.strip()调用:

>>> len(load_save_game(os.path.expanduser('~/Downloads/20_05_2016_16-04-31.txt')))
301

答案 1 :(得分:1)

正如Martijn所提到的,你应该直接迭代打开的文件。

我会写这样的代码:

save_game = map(json.loads, f)

<强> 编辑:

适用于Python2,因为map会返回list。如果您使用的是Python3,则需要将map括在list