导出为JSON时添加了额外的双引号和转义符
我正在用一个Python工具获取Twitter的数据,并把这些数据以JSON格式保存到我的硬盘上。我发现一个问题,就是整个推文的数据字符串被意外地用双引号包裹了起来。此外,实际的JSON格式中的所有双引号都被反斜杠转义了。
它们看起来像这样:
"{\"created_at\":\"Fri Aug 08 11:04:40 +0000 2014\",\"id\":497699913925292032,
我想避免这种情况。它应该是这样的:
{"created_at":"Fri Aug 08 11:04:40 +0000 2014" .....
我的输出文件代码是这样的:
with io.open('data'+self.timestamp+'.txt', 'a', encoding='utf-8') as f:
f.write(unicode(json.dumps(data, ensure_ascii=False)))
f.write(unicode('\n'))
这种意外的转义在后续处理步骤中读取JSON文件时会造成问题。
7 个回答
一个简单的方法可以解决这个问题,我用过的就是在进行数据存储之前,先使用 json 的加载功能,像下面这样:
import json
data = json.loads('{"foo": json.dumps([{"bar": 1}, {"baz": 2}])}')
with open('output.json','w') as f:
json.dump(data,f,indent=4)
将 escape_forward_slashes 设置为 False,可以防止斜杠(/)被转义。
解决方案:
ujson.dumps({"a":"aa//a/dfdf"}, escape_forward_slashes=False)
'{"a":"aa//a/dfdf"}'
默认情况下:
ujson.dumps({"a":"aa//a/dfdf"}, escape_forward_slashes=True)
'{"a":"aa\\/\\/a\\/dfdf"}'
为了帮助遇到类似问题的人,我用这个方法把从API调用获取的JSON格式数据保存到文件里。下面是一个示例,你可以根据自己的需要进行修改。
import json
# below is an example, this came for me from an API call
json_string = '{"address":{"city":"NY", "country":"USA"}}'
# dump the JSON data into file ( dont use json.dump as explained in other answers )
with open('direct_json.json','w') as direct_json:
direct_json.write(json_string)
direct_json.write("\n")
# load as dict
json_dict = json.loads(json_string)
# pretty print
print(json.dumps(json_dict, indent = 1))
# write pretty JSON to file
with open('formatted.json','w') as formatted_file:
json.dump(json_dict, formatted_file, indent=4)
还有一种情况会导致不必要的转义,就是你试图对已经用 json.dumps() 处理过的输出再使用 json.dump()。比如说:
import json, sys
json.dump({"foo": json.dumps([{"bar": 1}, {"baz": 2}])},sys.stdout)
这样会得到:
{"foo": "[{\"bar\": 1}, {\"baz\": 2}]"}
为了避免这种情况,你需要传递字典,而不是 json.dumps() 的输出,比如:
json.dump({"foo": [{"bar": 1}, {"baz": 2}]},sys.stdout)
这样就能输出你想要的结果:
{"foo": [{"bar": 1}, {"baz": 2}]}
(你可能会问,为什么要先用 json.dumps() 处理内部列表?其实我有另一个函数是从其他东西创建那个内部列表的,我以为从那个函数返回一个 json 对象是有意义的……结果并不是这样。)
你在对你的JSON字符串进行重复编码。data
已经是一个JSON字符串了,不需要再进行一次编码:
>>> import json
>>> not_encoded = {"created_at":"Fri Aug 08 11:04:40 +0000 2014"}
>>> encoded_data = json.dumps(not_encoded)
>>> print encoded_data
{"created_at": "Fri Aug 08 11:04:40 +0000 2014"}
>>> double_encode = json.dumps(encoded_data)
>>> print double_encode
"{\"created_at\": \"Fri Aug 08 11:04:40 +0000 2014\"}"
只需直接把这些写入你的文件中:
with open('data{}.txt'.format(self.timestamp), 'a') as f:
f.write(data + '\n')