显示带有非 ascii 字符的原始 JSON
Display raw JSON with non-ascii characters
我在终端中使用 Python3 显示原始 JSON 数据时遇到问题。我得到 json 作为来自 urllib 的响应:
r = urlopen(request)
response = r.read()
结果是一个字节串 b"..."
,其中一部分包含非 ASCII 字符,如 b"Chybn\u00e9 heslo"
,这应该给我这个 "Chybné heslo"
.
但我不知道如何解码它以显示 "Chybné heslo"
,如果我这样做:
print(b"Chybn\u00e9 heslo".decode('utf-8'))
我刚刚得到 "Chybn\u00e9 heslo"
。我在这里做错了什么?
使用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
如果它真的是一个有效的 JSON 字符串响应,它应该在字符串周围加上双引号,并且在这种情况下是一个完全 ASCII 响应,其 Unicode 代码点表示为 JSON 转义码。您可以使用 json
模块对其进行解码。这也将处理更复杂的 JSON 响应,包含列表和 key/value 对:
>>> import json
>>> json.loads(b'"Chybn\u00e9 heslo"')
'Chybné heslo'
同时查看 requests
模块(第 3 方),它将为您解码 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'
我在终端中使用 Python3 显示原始 JSON 数据时遇到问题。我得到 json 作为来自 urllib 的响应:
r = urlopen(request)
response = r.read()
结果是一个字节串 b"..."
,其中一部分包含非 ASCII 字符,如 b"Chybn\u00e9 heslo"
,这应该给我这个 "Chybné heslo"
.
但我不知道如何解码它以显示 "Chybné heslo"
,如果我这样做:
print(b"Chybn\u00e9 heslo".decode('utf-8'))
我刚刚得到 "Chybn\u00e9 heslo"
。我在这里做错了什么?
使用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
如果它真的是一个有效的 JSON 字符串响应,它应该在字符串周围加上双引号,并且在这种情况下是一个完全 ASCII 响应,其 Unicode 代码点表示为 JSON 转义码。您可以使用 json
模块对其进行解码。这也将处理更复杂的 JSON 响应,包含列表和 key/value 对:
>>> import json
>>> json.loads(b'"Chybn\u00e9 heslo"')
'Chybné heslo'
同时查看 requests
模块(第 3 方),它将为您解码 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'