Python 请求模块:urlencoding json 数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15737434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python requests module: urlencoding json data
提问by kevin
I'm working on an API wrapper. The spec I'm trying to build to has the following request in it:
我正在研究 API 包装器。我正在尝试构建的规范中有以下请求:
curl -H "Content-type:application/json" -X POST -d data='{"name":"Partner13", "email":"[email protected]"}' http://localhost:5000/
This request produces the following response from a little test server I setup to see exatly what headers/params etc are sent as. This little script produces:
这个请求从我设置的一个小测试服务器产生以下响应,以查看发送的标题/参数等。这个小脚本产生:
uri: http://localhost:5000/,
method: POST,
api_key: None,
content_type: application/json,
params: None,
data: data={"name":"Partner13", "email":"[email protected]"}
So that above is the result I want my python script to create when it hits the little test script.
所以上面是我希望我的 python 脚本在遇到小测试脚本时创建的结果。
I'm using the python requests module, which is the most beautiful HTTP lib I have ever used. So here is my python code:
我正在使用 python requests 模块,这是我用过的最漂亮的 HTTP 库。所以这是我的python代码:
uri = "http://localhost:5000/"
headers = {'content-type': 'application/json' }
params = {}
data = {"name":"Partner13", "email":"[email protected]"}
params["data"] = json.dumps(data)
r = requests.post(uri, data=params, headers=headers)
So simple enough stuff. Set the headers, and create a dictionary for the POST parameters. That dictionary has one entry called "data" which is the JSON string of the data I want to send to the server. Then I call the post. However, the result my little test script gives back is:
这么简单的东西。设置标题,并为 POST 参数创建一个字典。该字典有一个名为“data”的条目,它是我要发送到服务器的数据的 JSON 字符串。然后我打电话给邮局。但是,我的小测试脚本返回的结果是:
uri: http://localhost:5000/,
method: POST,
api_key: None,
content_type: application/json,
params: None,
data: data=%7B%22name%22%3A+%22Partner13%22%2C+%22email%22%3A+%22example%40example.com%22%7D
So essentially the json data I wanted to send under the data parameter has been urlendcoded.
所以基本上我想在 data 参数下发送的 json 数据已经被 urlendcoded 编码了。
Does anyone know how to fix this? I have looked through the requests documentation and cannot seem to find a way to not auto urlencode the send data.
有谁知道如何解决这一问题?我已经查看了请求文档,似乎无法找到一种不对发送数据进行自动 urlencode 的方法。
Thanks very much, Kevin
非常感谢,凯文
回答by John
When creating the object for the data keyword, simply assign a variable the result of json.dumps(data).
在为 data 关键字创建对象时,只需将 json.dumps(data) 的结果分配给一个变量。
Also, because HTTP POST can accept both url parameters as well as data in the body of the request, and because the requests.post function has a keyword argument named "params", it might be better to use a different variable name for readability. The requests docs use the variable name "payload", so thats what I use.
此外,因为 HTTP POST 可以接受 url 参数以及请求正文中的数据,并且由于 requests.post 函数有一个名为“params”的关键字参数,为了可读性,使用不同的变量名可能会更好。请求文档使用变量名称“payload”,这就是我使用的。
data = {"name":"Partner13", "email":"[email protected]"}
payload = json.dumps(data)
r = requests.post(uri, data=payload, headers=headers)
回答by minuteman3
Requests automatically URL encodes dictionaries passed as data here. John_GG's solution works because rather than posting a dictionary containing the JSON encoded string in the 'data' field it simply passes the JSON encoded string directly: strings are not automatically encoded. I can't say I understand the reason for this behaviour in Requests but regardless, it is what it is. There is no way to toggle this behaviour off that I can find.
请自动URL编码为数据传递字典这里。John_GG 的解决方案有效,因为它没有在“数据”字段中发布包含 JSON 编码字符串的字典,而是直接传递 JSON 编码字符串:字符串不会自动编码。我不能说我理解 Requests 中这种行为的原因,但无论如何,它就是这样。我无法找到关闭此行为的方法。
Best of luck with it, Kevin.
祝你好运,凯文。

