我一直在试图弄清楚如何使用python-requests
发送网址看起来像的请求:
http://example.com/api/add.json?name='hello'&data[]='hello'&data[]='world'
通常我可以建立一个字典并执行:
data = {'name': 'hello', 'data': 'world'}
response = requests.get('http://example.com/api/add.json', params=data)
对于我所做的大多数事情都适用。但是,我从上面打了url结构,我不知道如何在没有手动构建字符串的情况下在python中执行此操作。我可以做到,但不愿意。
请求库中是否存在我缺少的内容或某些我不知道的python功能?
另外你甚至称那种类型的参数为什么我可以更好地谷歌呢?
答案 0 :(得分:58)
您需要做的就是将其放在列表中并将密钥设为列表,如字符串:
data = {'name': 'hello', 'data[]': ['hello', 'world']}
response = requests.get('http://example.com/api/add.json', params=data)
答案 1 :(得分:7)
你所做的只是正确的。结果url与你期望的相同。
>>> payload = {'name': 'hello', 'data': 'hello'}
>>> r = requests.get("http://example.com/api/params", params=payload)
你可以看到结果网址:
>>> print(r.url)
http://example.com/api/params?name=hello&data=hello
根据url format:
特别是,对查询字符串进行编码时使用以下规则:
.
,-
,~
和_
保留为 - 是+
或%20
所以array[]
将不会如预期的那样,并将根据规则自动替换:
如果您构建了一个网址:
`Build URL: http://example.com/api/add.json?name='hello'&data[]='hello'&data[]='world'`
OutPut将是:
>>> payload = {'name': 'hello', "data[]": 'hello','data[]':'world'}
>>> r = requests.get("http://example.com/api/params", params=payload)
>>> r.url
u'http://example.com/api/params?data%5B%5D=world&name=hello'
这是因为复制将替换为网址中密钥的最后一个值,data[]
将替换为data%5B%5D
。
如果data%5B%5D
不是问题(如果服务器能够正确解析它),那么你可以继续使用它。
答案 2 :(得分:7)
如果使用请求模块的一个解决方案不是强制性的,则使用urllib
/ urllib2
组合:
payload = [('name', 'hello'), ('data[]', ('hello', 'world'))]
params = urllib.urlencode(payload, doseq=True)
sampleRequest = urllib2.Request('http://example.com/api/add.json?' + params)
response = urllib2.urlopen(sampleRequest)
它稍微冗长一点,并使用doseq(uence)技巧来编码url参数,但是当我不知道请求模块时我使用过它。
对于请求模块,@ Tomer提供的答案应该有效。
答案 3 :(得分:0)
某些api服务器希望将json-array作为url查询字符串中的值。请求参数不会创建json数组作为参数值。
我在类似问题上解决此问题的方法是使用urllib.parse.urlencode编码查询字符串,将其添加到url并将其传递给请求
例如
from urllib.parse import urlencode
query_str = urlencode(params)
url = "?" + query_str
response = requests.get(url, params={}, headers=headers)