如何在JSON中将中文字符编码为'gbk'以格式化URL请求参数字符串?

4 投票
2 回答
5130 浏览
提问于 2025-04-26 11:59

我想把一个字典转换成包含一些中文字符的json字符串,并用这个字符串来格式化一个网址请求的参数。

这是我的Python代码:

import httplib
import simplejson as json
import urllib

d={
  "key":"上海",
  "num":1
}

jsonStr = json.dumps(d,encoding='gbk')
url_encode=urllib.quote_plus(jsonStr)

conn = httplib.HTTPConnection("localhost",port=8885)
conn.request("GET","/?json="+url_encode)
res = conn.getresponse()

我期望得到的请求字符串是这样的:

GET /?json=%7B%22num%22%3A+1%2C+%22key%22%3A+%22%C9%CF%BA%A3%22%7D
                                                ------------
                                                     |
                                                     V
                       "%C9%CF%BA%A3" represent "上海" in format of 'gbk' in url.

但是我得到的是这样的:

GET /?json=%7B%22num%22%3A+1%2C+%22key%22%3A+%22%5Cu6d93%5Cu5a43%5Cu6363%22%7D
                                                ------------------------
                                                         |
                                                         v
           %5Cu6d93%5Cu5a43%5Cu6363  is 'some' format of chinese characters "上海"  

我还尝试过用 ensure_ascii=False 这个选项来转换json:

jsonStr = json.dumps(d,ensure_ascii=False,encoding='gbk')

但是没有成功。

那么,我该怎么做才能让它正常工作呢?谢谢。

暂无标签

2 个回答

2
"key":"上海",

你把源代码保存为UTF-8格式,所以这就是字节字符串 '\xe4\xb8\x8a\xe6\xb5\xb7'

jsonStr = json.dumps(d,encoding='gbk')

JSON格式只支持Unicode字符串。你可以使用 encoding 参数来强制 json.dumps 允许字节字符串,这样它会根据给定的编码自动解码成Unicode。

但是,字节字符串的编码实际上是UTF-8,而不是 'gbk',所以 json.dumps 解码时出错,结果变成了 u'涓婃捣'。这样就生成了错误的JSON输出 "\u6d93\u5a43\u6363",然后被URL编码成 %22%5Cu6d93%5Cu5a43%5Cu6363%22

要解决这个问题,你应该把传给 json.dumps 的输入改成正确的Unicode字符串(u''):

# coding: utf-8

d = {
    "key": u"上海",  # or u'\u4e0a\u6d77' if you don't want to rely on the coding decl
    "num":1
}
jsonStr = json.dumps(d)
...

这样你就能得到JSON "\u4e0a\u6d77",再编码成URL %22%5Cu4e0a%5Cu6d77%22

如果你 真的 不想在JSON中看到 \u 的转义字符,你可以设置 ensure_ascii=False,然后在URL编码之前对输出进行 .encode()。不过我不太推荐这样做,因为你需要考虑目标应用在URL参数中想要什么编码,这可能会带来一些麻烦。\u 版本被所有JSON解析器接受,并且在URL编码后通常不会长很多。

2

你几乎搞对了,使用 ensure_ascii=False 是正确的。这个方法可以这样用:

jsonStr = json.dumps(d, encoding='gbk', ensure_ascii=False).encode('gbk')

你需要告诉 json.dumps(),它要处理的字符串是 GBK 编码的,并且不要试图把它们转换成 ASCII 格式。然后你还得重新指定输出的编码,因为 json.dumps() 没有单独的选项来设置这个。

这个解决方案和这里的另一个答案很相似:https://stackoverflow.com/a/18337754/4323

所以这个方法能达到你想要的效果,不过我得提醒你,关于 URI 的标准似乎建议尽可能使用 UTF-8 编码。想了解更多,可以看看这里:https://stackoverflow.com/a/14001296/4323

撰写回答