繁体   English   中英

尝试附加JSON文件的Python错误

[英]Python error trying to append JSON file

我对Python比较陌生,所以我的问题可能很简单,但经过几天的尝试和搜索,我找不到任何东西。

因此,我构建了一个脚本来从Twitter流式传输数据,并将收集数据存储到json文件中,以便以后可以访问它并执行任何操作。 此脚本从单独的文件中提取用户凭据(如consumer keytokenaccess info以进行身份​​验证(我确信有更好,更安全的方法可以做到这一点,这只是目前的概念验证)使用这段代码:

with open('Twitter_Credentials.json', mode = 'a+') as tc:
            data = json.load(tc)
            if user not in data['names']:
                user_dict = dict()
                user_dict[user] = {'key':'','secret':'','token':'','token_secret':''}
                user_dict[user]['key'] = input('Twitter Consumer Key: ')
                user_dict[user]['secret'] = input('Twitter Consumer Secret: ')
                user_dict[user]['token'] = input('Twitter Access Token: ')
                user_dict[user]['token_secret'] = input('Twitter Access Secret: ')
                data['names'].append(user_dict)
                json.dump(data,tc, indent = 2, ensure_ascii = False)
                tc.close()

我遇到的问题是,如果我想将另一个用户及其凭据附加到此文件,我将继续收到此错误:

File "(filepath)", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

我已经做过的事情:

  • 使用'r''r+''w''w+'修改模式
  • load()dump()更改为loads()dumps()
  • 更改编码

使用'r+''w+'没有给我一个错误,但它确实复制了原始用户,因此它们出现了多次。 我想消除它,以便在它附加时它不会重复。 任何见解将不胜感激。 提前致谢。

JSON文件是包含单个JSON文档的文件。 如果您向其追加另一个JSON字符串,则它不再是JSON文件。

正如文档所说:

注意与picklemarshal不同,JSON不是框架协议,因此尝试使用相同的fp重复调用dump()来序列化多个对象将导致无效的JSON文件。


如果您实际上并未尝试将多个文档存储在一个文件中,则修复很简单:您要做的是打开文件,加载文件,修改数据,然后再次打开文件并覆盖它。 像这样:

with open('Twitter_Credentials.json', mode = 'r') as tc:
    data = json.load(tc)
if user not in data['names']:
    # blah blah
    with open('Twitter_Credentials.json', mode = 'w') as tc:
        json.dump(data, tc, indent = 2, ensure_ascii = False)

请注意,我使用的是w模式,而不是a模式,因为我们想要使用新文件覆盖旧文件,而不是将其添加到文件末尾。


如果想存储多个文档,那么你不能做到这一点与JSON。 幸运的是,基于JSON-JSONlines,NDJ等的非常简单的框架协议是常用的。 有三种或四种不同的这种格式存在细微差别,但所有这些格式的关键在于每个JSON文档本身都在一条线上,文档之间有换行符。

但是使用ensure_ascii=False意味着你没有转义字符串中的换行符,而indent=2意味着你在文档中的字段之间添加了更多的换行符,然后你没有做任何事情来在每个文档之后写一个换行符。 因此,您的输出不是有效的JSONlines,而是有效的JSON。

此外,即使您修复了所有这些,您也只执行一个json.load ,它只读取JSONlines文件中的第一个文档,然后将json.dump写入同一个文件,之后将写入第二个文档那一个,覆盖那里的一切。 你可能很容易最终覆盖,比如前一个第二个文档的一半,而另一半则留下了垃圾,以便稍后阅读。 所以,你需要重新思考你的逻辑。 至少,您想要执行与上面相同的操作,打开文件两次:

with open('Twitter_Credentials.json', mode = 'r') as tc:
    data = json.load(tc)
if user not in data['names']:
    # blah blah
    with open('Twitter_Credentials.json', mode = 'a') as tc:
        json.dump(data, tc)
        tc.write('\n')

这次我正在使用a模式,因为这次我们确实希望在现有文件的末尾添加一个新行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM