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

Bud*_*sey 23 python python-requests

我一直试图弄清楚如何使用python-requests发送网址的请求:

http://example.com/api/add.json?name='hello'&data[]='hello'&data[]='world'
Run Code Online (Sandbox Code Playgroud)

通常我可以构建一个字典并执行:

data = {'name': 'hello', 'data': 'world'}
response = requests.get('http://example.com/api/add.json', params=data)
Run Code Online (Sandbox Code Playgroud)

这适用于我所做的大多数事情.但是,我从上面打了url结构,我不知道如何在没有手动构建字符串的情况下在python中执行此操作.我可以做到,但不愿意.

在我丢失的请求库中有什么东西或者我不知道的一些python功能吗?

你甚至称那种类型的参数,所以我可以更好地谷歌吗?

Tom*_*ait 67

您需要做的就是将它放在一个列表上,并将密钥作为字符串列表:

data = {'name': 'hello', 'data[]': ['hello', 'world']}
response = requests.get('http://example.com/api/add.json', params=data)
Run Code Online (Sandbox Code Playgroud)

  • 我希望原用户找到了这个答案,因为它正好解决了 SendGrid API 的问题。谢谢@Tomer。 (2认同)

Arv*_*ind 7

你在做什么只是正确的。生成的网址与您期望的相同。

>>> payload = {'name': 'hello', 'data': 'hello'}
>>> r = requests.get("http://example.com/api/params", params=payload)
Run Code Online (Sandbox Code Playgroud)

您可以看到结果网址:

>>> print(r.url)
http://example.com/api/params?name=hello&data=hello
Run Code Online (Sandbox Code Playgroud)

根据网址格式

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

  • 字母(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'`
Run Code Online (Sandbox Code Playgroud)

输出将是:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

这是因为复制将被url中键的最后一个值data[]替换,并将被替换data%5B%5D

如果data%5B%5D不是问题(如果服务器能够正确解析),那么您可以继续进行。

源链接

  • 我同意你所说的一切。不幸的是,我遇到了一个 API(http://sendgrid.com/docs/API_Reference/Marketing_Emails_API/emails.html,查看“将多个电子邮件收件人添加到列表”),它需要多个相同的密钥。所以需要一种强制重复的方法,或者我需要手动构建参数字符串。 (2认同)

san*_*ora 7

如果使用请求模块的一个解决方案不是强制性的,则使用urllib/ urllib2combination:

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)
Run Code Online (Sandbox Code Playgroud)

它稍微冗长一点,并使用doseq(uence)技巧来编码url参数,但是当我不知道请求模块时我使用过它.

对于请求模块,@ Tomer提供的答案应该有效.