我想将dict转储为包含一些中文字符的json String,并使用该格式设置url请求参数。
这是我的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')
但没有运气。
那么,我怎样才能做到这一点?感谢。
答案 0 :(得分:2)
你几乎得到了ensure_ascii=False
。这有效:
jsonStr = json.dumps(d, encoding='gbk', ensure_ascii=False).encode('gbk')
你需要告诉json.dumps()
它将读取的字符串是GBK,并且它不应该尝试ASCII-fy它们。然后,您必须重新指定输出编码,因为json.dumps()
没有单独的选项。
此解决方案类似于此处的另一个答案:https://stackoverflow.com/a/18337754/4323
所以这就是你想要的,尽管我应该注意到URI的标准似乎说它们应该尽可能使用UTF-8。有关详情,请参阅此处:https://stackoverflow.com/a/14001296/4323
答案 1 :(得分:0)
"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"
,编码为网址%22%5Cu4e0a%5Cu6d77%22
。
如果确实不希望JSON中的\u
转义,您可以在URL编码之前确实ensure_ascii=False
然后.encode()
输出。但我不推荐它,因为你不得不担心目标应用程序在其URL参数中需要什么编码,这是一些痛苦的根源。 \u
版本被所有JSON解析器接受,并且一旦进行URL编码,通常不会更长。