在Python中解析包含"\u作为UTF-8字节"的JSON

3

我有一个来自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中正确解析这样的文件(以便获得字母á)?

1个回答

3

看起来他们使用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))

1
如果字符串是从文件中加载的,则此方法无法正常工作,因为在这种情况下,字符串为“'\u00c3\u00a1'”。 - user6247
你说的“它不起作用”是什么意思?字符串中是否包含反斜杠?如果有,你可以使用json.loads来解析这种表示法,或者使用ast.literal_eval - λuser
我在问题中提到的\u00c3\u00a1是JSON文件本身中保存的方式,这意味着当我在文本编辑器中查看文件时,我会看到确切的内容(此时Python并未参与)。因此,文件和从中加载的字符串都包含文字反斜杠。但是,当我使用json.loads时,它被错误地解析为á。 - user6247
1
你需要在解析后修复整个数据。我刚刚编辑了我的答案,添加了代码以展示如何修复它。 - λuser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接