Python requests模块发送JSON字符串而非x-www-form-urlencoded参数字符串
我原以为使用x-www-form-urlencoded格式的POST请求应该在请求的主体中发送一个经过URL编码的参数字符串。但是,当我这样做的时候
data = json.dumps({'param1': 'value1', 'param2': 'value2'})
Requests.post(url, data=data)
接收端的请求主体看起来是这样的:
{"param1": "value1", "param2": "value2"}
但我本来期待得到的是这个
param1=value1¶m2=value2
我该如何让请求以第二种形式发送数据呢?
3 个回答
13
简短回答和示例:
import requests
the_data = {"aaa": 1, "bbb": 2, "ccc": "yeah"}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
# Execute the post
requests.post("http://bla.bla.example.com", data=the_data, headers=headers)
# You have POSTed this HTTP body: aaa=1&bbb=2&ccc=yeah (note, although the content-type is called urlencoded the data is not in the URL but in the http body)
# to this url: "http://bla.bla.example.com"
Requests库会帮你把JSON格式的数据转换成url编码的字符串。
参考资料:
16
重要的是要说明,这个方法不适用于嵌套的json数据。也就是说,如果你的数据是这样的:
# Wrong
data = {'param1': {'a':[100, 200]},
'param2': 'value2',
'param3': False}
# You have to convert values into string:
data = {'param1': json.dumps({'a':[100, 200]}),
'param2': 'value2',
'param3': json.dumps(False)}
189
你之所以得到JSON格式的数据,是因为你明确调用了json.dumps
来生成一个JSON字符串。只要不这样做,你就不会得到JSON字符串。换句话说,把你的第一行改成这样:
data = {'param1': 'value1', 'param2': 'value2'}
正如文档所解释的,如果你把一个字典作为data
的值传入,它会被编码成表单格式;而如果你传入一个字符串,它会原样发送。
举个例子,在一个终端窗口中:
$ nc -kl 8765
在另一个终端窗口中:
$ python3
>>> import requests
>>> d = {'spam': 20, 'eggs': 3}
>>> requests.post("http://localhost:8765", data=d)
^C
>>> import json
>>> j = json.dumps(d)
>>> requests.post("http://localhost:8765", data=j)
^C
在第一个终端中,你会看到第一个请求的内容是这个(并且Content-Type是application/x-www-form-urlencoded
):
spam=20&eggs=3
…而第二个请求的内容是这个(没有Content-Type):
{"spam": 20, "eggs": 3}