Python中使用请求的查询字符串数组参数

时间:2014-04-09 21:58:29

标签: python python-requests

我一直在试图弄清楚如何使用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功能?

另外你甚至称那种类型的参数为什么我可以更好地谷歌呢?

4 个答案:

答案 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

特别是,对查询字符串进行编码时使用以下规则:

  • 字母(A-Z和a-z),数字(0-9)和字符.-~_保留为 - 是
  • SPACE编码为+%20
  • 所有其他字符编码为%HH十六进制表示,其中任何非ASCII字符首先编码为UTF-8(或其他指定编码)

所以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不是问题(如果服务器能够正确解析它),那么你可以继续使用它。

Source Link

答案 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)