[英]Use %20 instead of + for space in python query parameters
I have written the following python script, using python requests ( http://requests.readthedocs.org/en/latest/ ):我使用 python 请求( http://requests.readthedocs.org/en/latest/ )编写了以下 python 脚本:
import requests
payload = {'key1': 'value 1', 'key2': 'value 2'}
headers = {'Content-Type': 'application/json;charset=UTF-8'}
r = requests.get("http://example.com/service", params=payload, headers=headers,
auth=("admin", "password"))
If I look at the access log of the server, the incoming request is: /service?key1=value++1&key2=value+2如果我查看服务器的访问日志,传入的请求是:/service?key1=value++1&key2=value+2
However, the server expects ... value%20%201&
...但是,服务器期望 ... value%20%201&
...
I have read that using a + as a placeholder for a space is part of content type application/x-www-form-urlencoded, but clearly I have requested application/json.我已经读到使用 + 作为空格的占位符是内容类型 application/x-www-form-urlencoded 的一部分,但显然我已经请求了 application/json。
Anybody know how to use %20 as a space in query parameters of pythons requests?有人知道如何在pythons请求的查询参数中使用%20作为空格吗?
To follow up on @WeaselFox's answer, they introduced a patch that accepts a quote_via
keyword argument to urllib.parse.urlencode
.为了跟进@ WeaselFox的答案,他们介绍了接受一个补丁quote_via
关键字参数urllib.parse.urlencode
。 Now you could do this:现在你可以这样做:
import requests
import urllib
payload = {'key1': 'value 1', 'key2': 'value 2'}
headers = {'Content-Type': 'application/json;charset=UTF-8'}
params = urllib.parse.urlencode(payload, quote_via=urllib.parse.quote)
r = requests.get("http://example.com/service", params=params, headers=headers,
auth=("admin", "password"))
try it.尝试一下。
import urllib
urllib.urlencode(params)
http://docs.python.org/2/library/urllib.html#urllib.urlencode http://docs.python.org/2/library/urllib.html#urllib.urlencode
I only find urllib.parse.quote , which can replace space to %20
.我只找到urllib.parse.quote ,它可以将空格替换为%20
。
But quote
could not convert a dict.但是quote
无法转换字典。
so, We must use quote
to transform dict in advance.所以,我们必须提前使用quote
来转换dict。
#for python3
from urllib.parse import quote
payload = {'key1': 'value 1', 'key2': 'value 2'}
newpayload = {}
for (k, v) in payload.items():
newpayload[quote(k)] = quote(v)
print(newpayload)
#print result: {'key1': 'value%20%201', 'key2': 'value%202'}
# Now, you can use it in requests
this seems to be a known bug/issue in python :这似乎是 python 中的一个已知错误/问题:
http://bugs.python.org/issue13866 http://bugs.python.org/issue13866
I think you will have to go around this issue using urllib
and urllib2
and avoid requests.我认为您将不得不使用urllib
和urllib2
解决这个问题并避免请求。 look at the bug reports for some tips on how to do that.查看错误报告以获取有关如何执行此操作的一些提示。
We can use urllib2.Request to call url我们可以使用 urllib2.Request 来调用 url
import urllib2
send_params = {'key1': 'value 1', 'key2': 'value 2'}
new_send_params = []
for (k, v) in send_params.items():
new_send_params.append(k + "=" + urllib2.quote(v))
url = 'http://example.com/service?'+ '&'.join(new_send_params)
req = urllib2.Request(url)
response = urllib2.urlopen(req)
print "Request URL: " + url
#Request URL: http://example.com/service?key1=value%20&key2=value%202
print response.read()
#Python Master Request handler 2016-07-04 16:05:19.928132 . Your request path is /service?key1=value%20&key2=value%202
PYTHON 2.7蟒蛇 2.7
Override the urllib.quote_pluse with urllib.quote覆盖与urllib.quote的urllib.quote_pluse
The urlencoder uses urllib.quote_pluse to encode the data. urlencoder 使用 urllib.quote_pluse 对数据进行编码。
import requests
import urllib
urllib.quote_plus=urllib.quote # A fix for urlencoder to give %20
payload = {'key1': 'value 1', 'key2': 'value 2'}
headers = {'Content-Type': 'application/json;charset=UTF-8'}
param = urllib.urlencode(payload) #encodes the data
r = requests.get("http://example.com/service", params=param, headers=headers,
auth=("admin", "password"))
the output for param = urllib.urlencode(payload)
'key2=value%202&key1=value%20%201'
from urllib.parse import urlencode
def to_query_string(params):
return urlencode(params, doseq=True).replace('+', '%20')
You could pass a string to
params
instead of a dictionary, and manually handle the spaces.
您可以将字符串传递给
params
而不是字典,并手动处理空格。
Maybe something along the lines of
也许类似的东西
which can be used as 可以用作def to_query_string(p, s=''): for k in p: v = p[k] if isinstance(v, str): s += f'{k}={v}&'.replace(' ', '%20') elif isinstance(v, int): s += f'{k}={v}&' elif isinstance(v, list): for i in v: s += f'{k}={i}&' return s[:-1] # remove last '&'
min = 10 max = 30 params = {'query': f'score between {min} and {max}', 'limit': 1, 'information': ['name', 'location']} response = get('/api/dogs', params=to_query_string(params))
requests
uses internally quote()
from urllib.parse
requests
内部使用来自urllib.parse
quote()
import requests
from requests.utils import quote
url='https://api-adresse.data.gouv.fr/search/'
requests.get(url, params='q='+quote('rue du Jura')).url
https://api-adresse.data.gouv.fr/search/?q=rue%20du%20Jura
If you give a str/byte (and not a dict), requests
don't encode you params如果您提供 str/byte(而不是 dict),则requests
不会对您的参数进行编码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.