Как кодировать китайский символ как '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-кодирования.

Другие вопросы по тегам