如何将来自网络服务的带重音字符存储到数据库中?
我通过一个网络服务获取了一个单词:André
在Python中,这个值看起来是这样的:"Andr\u00c3\u00a9"。然后我用 json.loads
来解码这个值:
>>> import json
>>> json.loads('{"name":"Andr\\u00c3\\u00a9"}')
>>> {u'name': u'Andr\xc3\xa9'}
当我把上面的内容存储到一个utf8格式的MySQL数据库时,使用Django存储的数据看起来是这样的:
SomeObject.objects.create(name=u'Andr\xc3\xa9')
从mysql命令行查询名字这一列,或者在网页上显示出来,结果是:
André
在网页上以utf8格式显示:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我的数据库是设置为utf8格式的:
mysql> SHOW VARIABLES LIKE 'collation%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_unicode_ci |
| collation_server | utf8_unicode_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)
mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
我该如何从网络服务中获取单词André,正确地存储到数据库中而不丢失数据,并在网页上以原始形式显示出来呢?
1 个回答
6
问题出在你传给 json.loads() 的字符串上。这里的 \u00c3 是“带波浪线的 A”,而 \00a9 是版权符号。正确的 é 应该是 \u00e9。
可能这个字符串是发送方用 UTF-8 编码的,而接收方却用 ISO-8859-1 解码了。
比如,如果你运行下面这个 Python 脚本:
# -*- encoding: utf-8 -*-
import json
data = {'name': u'André'}
print('data: {0}'.format(repr(data)))
code = json.dumps(data)
print('code: {0}'.format(repr(code)))
conv = json.loads(code)
print('conv: {0}'.format(repr(conv)))
name = conv['name']
print(u'Name is {0}'.format(name))
输出应该是这样的:
data: {'name': u'Andr\xe9'}
code: '{"name": "Andr\\u00e9"}'
conv: {u'name': u'Andr\xe9'}
Name is André
在 Python 2.x 中处理 Unicode 有时候会让人头疼。不幸的是,Django 目前还不支持 Python 3。