Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将汉字编码为';gbk';在json中,如何格式化url请求参数字符串?_Python_Json_Unicode_Urlencode_Gbk - Fatal编程技术网

Python 如何将汉字编码为';gbk';在json中,如何格式化url请求参数字符串?

Python 如何将汉字编码为';gbk';在json中,如何格式化url请求参数字符串?,python,json,unicode,urlencode,gbk,Python,Json,Unicode,Urlencode,Gbk,我想将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

我想将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 "上海"  
我还尝试使用
确保ascii=False
选项转储json:

jsonStr = json.dumps(d,ensure_ascii=False,encoding='gbk')
但是没有运气


那么,我怎样才能让这一切顺利进行呢?谢谢。

确保ascii=False
您几乎可以得到它。这项工作:

jsonStr = json.dumps(d, encoding='gbk', ensure_ascii=False).encode('gbk')
您需要告诉
json.dumps()
它将读取的字符串是GBK,并且它不应该尝试对它们进行ASCII校验。然后必须重新指定输出编码,因为
json.dumps()
对此没有单独的选项

此解决方案类似于此处的另一个答案:

所以这就是您想要的,尽管我应该注意到URI的标准似乎说只要可能,它们就应该使用UTF-8。有关详细信息,请参见此处:

您将源代码保存为UTF-8,因此这是字节字符串
'\xe4\xb8\x8a\xe6\xb5\xb7'

jsonStr = json.dumps(d,encoding='gbk')
JSON格式仅支持Unicode字符串。
encoding
参数可用于强制
json.dump
允许字节字符串,并使用给定的编码将其自动解码为Unicode

但是,字节字符串的编码实际上是UTF-8而不是
'gbk'
,因此
json.dumps
解码错误,给出
u'涓婃捣'。然后,它生成不正确的JSON输出
“\u6d93\u5a43\u6363”
,该输出将URL编码为
%22%5Cu6d93%5Cu5a43%5Cu6363%22

要解决此问题,应将
json.dumps
的输入设置为正确的Unicode(
u'
)字符串:

这将获得JSON
“\u4e0a\u6d77”
,编码为URL
%22%5Cu4e0a%5Cu6d77%22


如果您确实不希望JSON中转义
\u
,您确实可以
确保ascii=False
,然后
.encode()
在URL编码之前输出。但我不推荐这样做,因为这样您就不得不担心目标应用程序在其URL参数中需要什么编码,这会带来一些麻烦。
\u
版本为所有JSON解析器所接受,并且通常在URL编码后不会太长。

感谢john清楚地解释了所有内容。非常有用。感谢您指出我对
json.dumps()
编码的参数的误解。但是仍然有一些东西让我困惑。如果我设置
key=u'上海',我得到了unicode的
,对吗?所以当我在控制台中键入
key
时,我会得到
u'\u4e0a\u6d77'
,但是
key.encode('utf8')
生成
'\xe4\xb8\x8a\xe6\xb5\xb7'
,我知道python使用unicode作为默认编码,unicode和utf8是一样的吗?或者只是另一种编码格式?
u'\u4e0a\u6d77'
'\xe4\xb8\x8a\xe6\xb5\xb7'
之间的关系是什么?数据是什么上海' 还是存储在python的内存中?非常混乱。Unicode字符串是一个字符序列,编号为0x000000–0x10FFFF。字节字符串是一个字节序列,编号为0x00–0xFF。有许多编码将部分或全部字符映射到一个或一个字节序列。许多但并非所有编码都是ASCII兼容的,因为每个字节0x00-0x7F直接映射到具有相同数字的Unicode字符。将所有字符映射到字节序列的编码称为UTF。UTF-8通常被认为是最好的,因为它是最紧凑的ASCII兼容UTF。Unicode不是一种编码,但Microsoft在Notepad等应用程序的接口中称UTF-16LE编码为“Unicode”,这让人感到困惑。UTF-16LE与ASCII不兼容,通常作为交换格式存在问题,但许多系统将其用作内部存储格式,包括Windows下的Python 2.x。但在其他环境中,Python可能使用其他编码。从所有平台上的Python3.3开始,它在多种编码之间切换。作为Python脚本作者,您通常不需要关心幕后的存储格式。
jsonStr = json.dumps(d,encoding='gbk')
# 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)
...