显示带有非ascii字符的原始JSON

时间:2017-10-24 19:01:17

标签: python-3.x unicode decoding

我在使用Python3在终端中显示原始JSON数据时遇到问题。我把json作为来自urllib的回复:

{% extends 'base.html' %}
{% block midRow %}
    <p>{{ fpn }}</p>
    <p>{{ spn }}</p>
{% endblock %}

结果是一个字节字符串r = urlopen(request) response = r.read() ,其中一部分包含非{ASCII}字符,如b"...",它应该给我b"Chybn\\u00e9 heslo"

但如果我这样做,我就不知道如何解码它以显示"Chybné heslo"

"Chybné heslo"

我得到print(b"Chybn\\u00e9 heslo".decode('utf-8')) 。我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

使用unicode-escape编解码器:

byte_str = b"Chybn\u00e9 heslo"
print(byte_str.decode('unicode-escape')) # Chybné heslo

您遇到问题的原因是字节字符串\u00e9不是unicode代码点 它只是一个字节序列:

>>> len(b'\u00e9') # whereas len('\u00e9') == 1
6 

>>> [b for b in b'\u00e9']
[92, 117, 48, 48, 101, 57]

这些字节也是UTF-8字节,因此当您使用此编码对它们进行解码时,您将获得相应的字符序列:

>>> b'\u00e9'.decode('utf-8')
'\\u00e9'

>>> [chr(b) for b in b'\u00e9'] # decoding in 'byte-by-byte' mode
['\\', 'u', '0', '0', 'e', '9']

另请注意,\\\在某些字符串中是等效的(有关详细信息,请查看this )。 例如:

>>> b'\\u' == b'\u'
True
>>> b'\\u00e9' == b'\u00e9'
True
>>> b'\\n' == b'\n'
False

>>> '\\u00e9' == '\u00e9'
False

>>> '\\z' == '\z' 
True

答案 1 :(得分:1)

如果它确实是一个有效的JSON字符串响应,它应该在字符串周围有双引号,并且这种情况是完全ASCII响应,Unicode代码点表示为JSON转义码。您可以使用json模块对其进行解码。这将处理更复杂的JSON响应,包含列表和键/值对:

>>> import json
>>> json.loads(b'"Chybn\\u00e9 heslo"')
'Chybné heslo'

另请查看requests模块(第三方),它将为您解码JSON:

>>> import requests
>>> r = requests.get('http://date.jsontest.com')
>>> r.text
'{\n   "time": "06:58:22 AM",\n   "milliseconds_since_epoch": 1508914702539,\n   "date": "10-25-2017"\n}\n'
>>> r.json()
{'time': '06:58:22 AM', 'milliseconds_since_epoch': 1508914702539, 'date': '10-25-2017'}
>>> D = r.json()
>>> D['time']
'06:58:22 AM'