我有一个来自Facebook“下载你的数据”功能的JSON文件,但是它没有将Unicode字符转义为其代码点编号,而是作为UTF-8字节序列进行了转义。
例如,字母á(U+00E1)在JSON文件中被转义为\u00c3\u00a1
而不是\u00e1
。0xC3 0xA1是U+00E1的UTF-8编码。
在Python 3中的json
库将其解码为á,对应于U+00C3和U+00A1。
有没有一种方法可以在Python中正确解析这样的文件(以便获得字母á)?
看起来他们使用utf-8将Unicode字符串编码为字节,然后将字节转换为JSON。这是他们的非常糟糕的行为。
Python 3示例:
>>> '\u00c3\u00a1'.encode('latin1').decode('utf-8')
'á'
您需要解析JSON并遍历整个数据以修复它:
def visit_list(l):
return [visit(item) for item in l]
def visit_dict(d):
return {visit(k): visit(v) for k, v in d.items()}
def visit_str(s):
return s.encode('latin1').decode('utf-8')
def visit(node):
funcs = {
list: visit_list,
dict: visit_dict,
str: visit_str,
}
func = funcs.get(type(node))
if func:
return func(node)
else:
return node
incorrect = '{"foo": ["\u00c3\u00a1", 123, true]}'
correct_obj = visit(json.loads(incorrect))
json.loads
来解析这种表示法,或者使用ast.literal_eval
。 - λuser\u00c3\u00a1
是JSON文件本身中保存的方式,这意味着当我在文本编辑器中查看文件时,我会看到确切的内容(此时Python并未参与)。因此,文件和从中加载的字符串都包含文字反斜杠。但是,当我使用json.loads
时,它被错误地解析为á。 - user6247