使用 python json.loads 解析 unicode 输入

Posted

技术标签:

【中文标题】使用 python json.loads 解析 unicode 输入【英文标题】:Parsing unicode input using python json.loads 【发布时间】:2011-01-15 02:36:11 【问题描述】:

在 Python 中加载 JSON 字符串的最佳方式是什么?

我想像这样使用 json.loads 来处理 unicode:

import json
json.loads(unicode_string_to_load)

我也尝试提供值为“utf-16”的“encoding”参数,但错误并没有消失。

完整的 SSCCE 错误:

# -*- coding: utf-8 -*-
import json
value = '"foo" : "bar"'
print(json.loads(value)['foo'])     #This is correct, prints 'bar'

some_unicode = unicode("degradé")  
#last character is latin e with acute "\xe3\xa9"
value = '"foo" : "' + some_unicode + '"'
print(json.loads(value)['foo'])            #incorrect, throws error

错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 
6: ordinal not in range(128)

【问题讨论】:

您有任何显示问题的源数据吗? 我收到此错误。 (UnicodeDecodeError: 'utf16' codec can't decode byte 0x38 in position 6: truncated data) 我使用这个命令:json.loads(response, encoding='utf-16')。对于许多 unicode 字符来说,这个错误也会随之而来...... .....我认为我们需要稍微讨论一下“源数据”的含义...... 源数据是巨大的 unicode 编码字符串,我在这里无法通过..., 然后粘贴 一些。我们要继续做的事情...... 【参考方案1】:

OP 澄清(在评论中!)...:

源数据是巨大的 unicode 编码 字符串

那么你必须知道它使用的许多 unicode 编码中的 哪个 -- 显然不是 'utf-16',因为它失败了,但还有很多其他编码 -- 'utf-8' 、“iso-8859-15”等。您可以全部尝试,直到其中一个有效,或者print repr(str_to_load[:80]) 并将其显示的内容粘贴为您的问题的编辑,以便我们可以代表您猜测!-)。

【讨论】:

在加载过程中很难识别特定的编码,因为源数据可能包含来自世界各种语言的字符。有没有办法检测编码类型? str_to_load 不断变化,utf-8 适用于某些人,utf-32 适用于某些人......但我如何自动检测它? 那个字符串是'"successful":true, "data":[76,"posting_id":"1753178","site_tender_id":"3188446' 尝试猜测字节串的编码——试试chardet.feedparser.org。您显示的字符串是 ASCII(根据定义,它也是有效的 utf-8,也是有效的 iso-8859-1 等:ASCII 是大多数编码的常见子集!)所以不可能猜测它是什么潜在的非 ASCII 编码可能在。UnicodeDecodeError 消息带有第一个有问题字节的确切索引,因此当您确实遇到错误时,请显示以该索引为中心的 80 长字节字符串的 repr。 当我阅读整个字符串时,我发现了 unicode 字符,请在下一个字符串中查看它... "Lucaya, Grand Bahama; 4 Bedroom, 3 \xbd Bathroom"【参考方案2】:

我使用 'latin-1' 将字符串类型转换为 unicode 字符串修复了错误:

UnicodeDecodeError: 'utf16' codec can't decode byte 0x38 in 
position 6: truncated data

固定代码:

import json

ustr_to_load = unicode(str_to_load, 'latin-1')

json.loads(ustr_to_load)

然后不会抛出错误。

【讨论】:

顺便说一句,latin-1iso-8859-1 的旧名称,而现在你更可能看到iso-8859-15——唯一的区别是后者包括欧元符号。如果您使用-1 解码并且字符串是使用-15 编码的,则基本上没问题,但是当您打印或显示欧元符号时,它们看起来会非常奇特。【参考方案3】:

使用 django,您可以使用 SimpleJSON 并使用加载而不是加载。

from django.utils import simplejson

simplejson.loads(str_to_load, "utf-8")

【讨论】:

这不再适用于 django,因为它使用 python 自带的默认值【参考方案4】:

我找到的最简单的方法是

import simplejson as json

这样你的代码保持不变

json.loads(str_to_load)

参考:https://simplejson.readthedocs.org/en/latest/

【讨论】:

以上是关于使用 python json.loads 解析 unicode 输入的主要内容,如果未能解决你的问题,请参考以下文章

python 解析json loads dumps

Python 的 json.loads 的数据输入必须是啥格式?

Python json.loads()

python json.loads 报错 json.decoder.JSONDecodeError

python——json.loads避坑

json解析模块