Как кодировать китайский символ как 'gbk' в json, чтобы отформатировать параметр запроса URL-адреса String?
Я хочу вывести dict как строку json, которая содержит несколько китайских символов, и отформатировать параметр запроса 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 "上海"
Я также пытался сбросить JSON с ensure_ascii=False
опция:
jsonStr = json.dumps(d,ensure_ascii=False,encoding='gbk')
но не повезло.
Итак, как я могу сделать эту работу? Благодарю.
2 ответа
Вы почти получили это с ensure_ascii=False
, Это работает:
jsonStr = json.dumps(d, encoding='gbk', ensure_ascii=False).encode('gbk')
Вы должны сказать json.dumps()
что строки, которые он будет читать, являются GBK, и что он не должен пытаться их ASCII-поиска. Затем вы должны заново указать выходную кодировку, потому что json.dumps()
не имеет отдельной опции для этого.
Это решение похоже на другой ответ здесь: /questions/28949112/sohranenie-tekstov-utf-8-v-jsondumps-kak-utf8-a-ne-kak-escape-posledovatelnost/28949144#28949144
Так что это делает то, что вы хотите, хотя я должен отметить, что стандарт для URI, кажется, говорит, что они должны быть в UTF-8, когда это возможно. Подробнее об этом см. Здесь: /questions/45281425/kak-vedet-sebya-brauzer-kodiruyuschij-url/45281439#45281439
"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
правильный Юникод (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
,
Если вы действительно не хотите \u
в вашем JSON вы действительно можете ensure_ascii=False
а потом .encode()
вывод перед URL-кодированием. Но я бы не рекомендовал это, так как вам пришлось бы беспокоиться о том, какая кодировка требуется целевому приложению в его параметрах URL, что является источником некоторой боли. \u
Версия принимается всеми анализаторами JSON и обычно не намного длиннее после URL-кодирования.