1

我试图在运行 mysql 查询的 Linux 服务器上运行 Python 中的脚本,该查询会产生一些希伯来语字符串(为了简化而在此处设置),如下所示:

#!/usr/bin/env  python
# -*- coding: utf-8 -*-
import cgi
import cgitb;cgitb.enable()
import sys
import urllib
import base64
from MySQL import sql
print """Content-Type: text/html\n"""
s = sql()
s.run("SET NAMES utf8;")
query = "SELECT page FROM pages"
results = s.run(query)
s.close()
ans = {}
ans['count'] = 0
ans['items'] = []    
for res in results:
    page = result[0].encode('utf-8')
    print "====="+page+"======"
    ans['items'].append({
           'td0':page
    })
print ans
s.close()

这尴尬地打印

"Content-Type: text/html"

====/מפת-זרזיר/גריפאת/1/====
{'count': 0, 'items': [{ 'td0': '/\xd7\x9e\xd7\xa4\xd7\xaa-\xd7\x96\xd7\xa8\xd7\x96\xd7\x99\xd7\xa8/\xd7\x92\xd7\xa8\xd7\x99\xd7\xa4\xd7\x90\xd7\xaa/1/'}]}

为什么哦为什么字典中的页面会丢失编码???我不知道为什么会这样。任何帮助将不胜感激。

谢谢

4

2 回答 2

5

您不应手动对数据进行编码。请改用该json模块,并将数据保留为 Unicode:

import json

for res in results:
    page = result[0]
    print "====={}======".format(page.encode('utf8')
    ans['items'].append({
        'td0':page
    })

print json.dumps(ans)

json模块将为您处理编码。

您正在打印 python 字典,而不是 JSON 映射,并且 Python 对字符串中的字节使用字符串文字表示。此表示使用\x..转义来表示任何不可打印的字符。由于您是直接打印 UTF-8 数据,因此数据包含许多不可打印的字节,但数据仍然存在:

>>> print '/\xd7\x9e\xd7\xa4\xd7\xaa-\xd7\x96\xd7\xa8\xd7\x96\xd7\x99\xd7\xa8/\xd7\x92\xd7\xa8\xd7\x99\xd7\xa4\xd7\x90\xd7\xaa/1/'.decode('utf8')
/מפת-זרזיר/גריפאת/1/

如果我采用您的示例值并json另一方面使用该模块会产生有效的 JSON 输出:

>>> ans = {'count': 0, 'items': []}
>>> ans['items'].append('/\xd7\x9e\xd7\xa4\xd7\xaa-\xd7\x96\xd7\xa8\xd7\x96\xd7\x99\xd7\xa8/\xd7\x92\xd7\xa8\xd7\x99\xd7\xa4\xd7\x90\xd7\xaa/1/'.decode('utf8'))
>>> import json
>>> print json.dumps(ans)
{"count": 0, "items": ["/\u05de\u05e4\u05ea-\u05d6\u05e8\u05d6\u05d9\u05e8/\u05d2\u05e8\u05d9\u05e4\u05d0\u05ea/1/"]}

JSON 允许使用\u....转义码,并且该模块使用转义码来表示非 ASCII 和不可打印的字符。这是正常的,兼容的 JSON 解码器会很好地读取它。

于 2013-05-07T13:35:06.680 回答
0

这源于使用:创建一个字符串"=====" + page + "====="并打印它,以及打印字典将使用repr(ans)并且表示可能不同的事实。不过,您并没有丢失编码。

编辑

正如 Martijn 所说,json如果实际上这是您的目的,您可以使用模块创建一个新字符串。如果是这样,您不应该事先打印该行,否则某些客户端可能无法解析数据(假设您正在制作 API)。

于 2013-05-07T13:36:16.357 回答