Python请求模块:对json数据进行urlencoding
Posted
技术标签:
【中文标题】Python请求模块:对json数据进行urlencoding【英文标题】:Python requests module: urlencoding json data 【发布时间】:2013-03-22 04:08:41 【问题描述】:我正在开发 API 包装器。我正在尝试构建的规范中包含以下请求:
curl -H "Content-type:application/json" -X POST -d data='"name":"Partner13", "email":"example@example.com"' http://localhost:5000/
这个请求从我设置的一个小测试服务器产生以下响应,以查看发送的标头/参数等。这个小脚本产生:
uri: http://localhost:5000/,
method: POST,
api_key: None,
content_type: application/json,
params: None,
data: data="name":"Partner13", "email":"example@example.com"
以上是我希望我的 python 脚本在遇到小测试脚本时创建的结果。
我正在使用 python requests 模块,这是我用过的最漂亮的 HTTP 库。所以这是我的python代码:
uri = "http://localhost:5000/"
headers = 'content-type': 'application/json'
params =
data = "name":"Partner13", "email":"example@exmaple.com"
params["data"] = json.dumps(data)
r = requests.post(uri, data=params, headers=headers)
这么简单的东西。设置标题,并为 POST 参数创建字典。该字典有一个名为“数据”的条目,它是我要发送到服务器的数据的 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
所以本质上我想在data参数下发送的json数据已经被urlendcode了。
有谁知道如何解决这个问题?我查看了请求文档,似乎找不到不自动对发送数据进行 urlencode 的方法。
非常感谢, 凯文
【问题讨论】:
您的 curl 示例中的数据不是有效的 json。它是表单编码和 json 的混合体。 【参考方案1】:请求会自动对作为数据 here 传递的字典进行 URL 编码。 John_GG 的解决方案之所以有效,是因为它不是在“数据”字段中发布包含 JSON 编码字符串的字典,而是直接传递 JSON 编码字符串:字符串不会自动编码。我不能说我理解 Requests 中这种行为的原因,但无论如何,它就是这样。我无法找到关闭此行为的方法。
祝你好运,凯文。
【讨论】:
你所说的“这里”是编码url参数,因为它们进入url,当然是url编码的。在requests post函数签名中,“params”指的是url参数,而“data”指的是POST body。 @John_GG 实际上这也用于对请求正文进行编码。调用堆栈类似于Request.init()
--> PreparedRequest.prepare()
--> PreparedRequest.prepare_body()
--> RequestEncodingMixin._encode_params()
。这似乎是自动处理带有application/x-www-form-urlencoded
内容的请求。【参考方案2】:
在为 data 关键字创建对象时,只需将 json.dumps(data) 的结果赋值给一个变量。
另外,因为 HTTP POST 可以接受 url 参数以及请求正文中的数据,并且因为 requests.post 函数有一个名为“params”的关键字参数,所以使用不同的变量名可能会更好为了可读性。请求文档使用变量名“payload”,这就是我使用的。
data = "name":"Partner13", "email":"example@exmaple.com"
payload = json.dumps(data)
r = requests.post(uri, data=payload, headers=headers)
【讨论】:
以上是关于Python请求模块:对json数据进行urlencoding的主要内容,如果未能解决你的问题,请参考以下文章
Python requests模块paramsdatajson的区别