Используйте %20 вместо + для пробела в параметрах запроса python

Я написал следующий python script, используя запросы python (http://requests.readthedocs.org/en/latest/):

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"))

Если я посмотрю журнал доступа на сервере, входящий запрос: ?/Услуга ключ1 = значение ++ 1 & ключ2 = значение + 2

Однако сервер ожидает... value%20%201&...

Я читал, что использование a + в качестве заполнителя для пробела является частью приложения типа контента /x -www-form-urlencoded, но, очевидно, я запросил приложение /json.

Кто-нибудь знает, как использовать %20 ​​в качестве пробела в параметрах запроса запросов pythons?

Ответ 1

Чтобы ответить на ответ @WeaselFox, они представили патч, который принимает аргумент ключевого слова quote_via в urllib.parse.urlencode. Теперь вы можете сделать это:

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"))

Ответ 3

Я нахожу urllib.parse.quote, который может заменить пробел на %20.

Но quote не смог преобразовать dict.

поэтому мы должны использовать 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

Ответ 4

это, кажется, известная ошибка/проблема в python:

http://bugs.python.org/issue13866

Думаю, вам придется обойти эту проблему с помощью urllib и urllib2 и избежать запросов. посмотрите на сообщения об ошибках для некоторых советов о том, как это сделать.

Ответ 5

Мы можем использовать 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