2012-09-21 6 views
6

Ich versuche, etwas Automatisierung in einem Python-Skript zu tun, und ich habe ein Problem festgestellt. Ich versuche, einen POST an einen Server zu senden. jedochÜbergabe des '+' Zeichen in einer POST-Anfrage in Python

url = 'http://www.example.com' 
params = {'arg0': 'value', 'arg1': '+value'} 

f = urllib.urlopen(url, urllib.urlencode(params)) 
print f.read() 

Ich habe eine wireshark Erfassung der äquivalenten Browser Operation durchgeführt, in dem die zweiten arg, arg1 als +value übergeben wird, wenn ich es mit Python tue die +-%2B geändert wird, das heißt

Line-based text data: application/x-www-form-urlencoded 
arg0=value&arg1=%2Bvalue 

wenn es sein sollte:

Line-based text data: application/x-www-form-urlencoded 
arg0=value&arg1=+value 

ich auch die Anfragen Modul verwendet haben und es scheint s das Gleiche zu tun.

url = 'http://www.example.com' 
params = {'arg0': 'value', 'arg1': '+value'} 

f = requests.post(url, params) 

Google ist nicht dein Freund, wenn Sie ein Problem haben auf ‚+‘ im Zusammenhang, wie es sonst für so viel fangen alle zu sein scheint.

+0

Welche Version von Anfragen verwenden Sie? – root

+0

Ich habe heute eine Pip Installation Anfragen - 0.14.0 –

+5

"Google ist nicht dein Freund, wenn Sie ein Problem im Zusammenhang mit '+'" haben - Für die Suche nach Sonderzeichen gibt es spezielle Suchmaschinen wie http://symbolhound.com/ – l4mpi

Antwort

7

Das Zeichen + ist die richtige Kodierung für ein Leerzeichen, wenn GET- oder POST-Daten angegeben werden. Daher muss ein Literal + auch mit Escapezeichen versehen werden, damit es nicht in ein Leerzeichen am anderen Ende decodiert wird. Siehe RFC 2396, section 2.2, section 3.4 und die HTML specification, application/x-www-form-urlencoded section:

Steuer Namen und Werte entkommen sind. Leerzeichen werden durch "+" ersetzt, und reservierte Zeichen werden wie in , Abschnitt 2.2 beschrieben, ausgeblendet.

Wenn Sie Daten einer Anwendung veröffentlichen, die keine + Charakter in einen Raum nicht dekodieren, sondern solche Daten als wörtliche Pluszeichen behandelt stattdessen müssen Sie Ihre Parameter kodieren selbst die urllib.quote function stattdessen verwenden, die Angabe, dass die + Zeichen nicht codiert werden:

import urllib 
def urlencode_withoutplus(query): 
    if hasattr(query, 'items'): 
     query = query.items() 
    l = [] 
    for k, v in query: 
     k = urllib.quote(str(k), safe=' /+') 
     v = urllib.quote(str(v), safe=' /+') 
     l.append(k + '=' + v) 
    return '&'.join(l) 

Demo:

>>> urlencode_withoutplus({'arg0': 'value', 'arg1': '+value'}) 
'arg0=value&arg1=+value' 

Bei Verwendung requests, können Sie einfach im Ergebnis der obigen Funktion als data Wert übergeben, aber in diesem Fall müssen Sie manuell den Inhaltstyp festlegen:

requests.post(url, urlencode_withoutplus(query), 
    headers={'Content-Type': 'application/x-www-form-urlencoded'}) 
+0

Das scheint den entgegengesetzten Weg zu gehen, den ich wollte. Willst du damit sagen, dass ich eine urllib.quote (params ['arg1']) machen soll, bevor ich einen urllib.urlencode tue, weil das nur '% 252Bvalue' ergibt, wenn ich auf wireshark capture. –

+0

@DouglasKastle: Nein, Sie verwenden dieses * anstelle * von urllib.urlencode. –

+0

Entschuldigung, ich sah deine Antwort, bevor sie fertig war. –

4
urllib2.quote(' ')  # '%20' 
urllib2.unquote('%20') # ' ' 

Warum also nicht nur den Parameter Teil des Zitat:

f = urllib.urlopen(url, urllib.unquote(urllib.urlencode(params))) 
+0

Interessant, für diesen Fall wird das wahrscheinlich ausreichen, ich stelle mir vor, dass es einige Typen gibt, die geschützt werden müssen. –

Verwandte Themen