如何将来自网络服务的带重音字符存储到数据库中?

4 投票
1 回答
3112 浏览
提问于 2025-04-15 22:23

我通过一个网络服务获取了一个单词: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。

撰写回答