Python, fonction opposée urllib.urlencode

88

Comment puis-je convertir des données après le traitement urllib.urlencodeen dict? urllib.urldecoden'existe pas.

Artyom
la source

Réponses:

124

Comme les docs pour urlencodedire,

Le module urlparse fournit les fonctions parse_qs () et parse_qsl () qui sont utilisées pour analyser les chaînes de requête en structures de données Python.

(Dans les anciennes versions de Python, ils étaient dans le cgimodule). Ainsi, par exemple:

>>> import urllib
>>> import urlparse
>>> d = {'a':'b', 'c':'d'}
>>> s = urllib.urlencode(d)
>>> s
'a=b&c=d'
>>> d1 = urlparse.parse_qs(s)
>>> d1
{'a': ['b'], 'c': ['d']}

La différence évidente entre le dictionnaire d'origine det le dictionnaire "aller-retour" d1est que ce dernier a des listes (élément unique, dans ce cas) comme valeurs - c'est parce qu'il n'y a pas de garantie d'unicité dans les chaînes de requête, et cela peut être important à votre application pour savoir quelles valeurs multiples ont été données pour chaque clé (c'est-à-dire que les listes ne seront pas toujours à un seul élément ;-).

Comme alternative:

>>> sq = urlparse.parse_qsl(s)
>>> sq  
[('a', 'b'), ('c', 'd')]
>>> dict(sq)
{'a': 'b', 'c': 'd'}

vous pouvez obtenir une séquence de paires (urlencode accepte également un tel argument - dans ce cas, il préserve l'ordre, alors que dans le cas dict, il n'y a pas d'ordre à conserver ;-). Si vous savez qu'il n'y a pas de "clés" en double, ou que vous ne vous souciez pas de savoir s'il y en a, alors (comme je l'ai montré) vous pouvez appeler dictpour obtenir un dictionnaire avec des valeurs hors liste. En général, cependant, vous devez considérer ce que vous voulez faire si des doublons sont présents (Python ne décide pas cela en votre nom ;-).

Alex Martelli
la source
1
Réponse très complète. Impressionnant!
Hartley Brody
Votez pour Python 2, mais Python 3 est tout dans le urllibmodule. Voir la réponse @phobie.
openwonk
18

Code Python 3 pour la solution d'Alex:

>>> import urllib.parse
>>> d = {'a':'b', 'c':'d'}
>>> s = urllib.parse.urlencode(d)
>>> s
'a=b&c=d'
>>> d1 = urllib.parse.parse_qs(s)
>>> d1
{'a': ['b'], 'c': ['d']}

L'alternative:

>>> sq = urllib.parse.parse_qsl(s)
>>> sq
[('a', 'b'), ('c', 'd')]
>>> dict(sq)
{'a': 'b', 'c': 'd'}

parse_qsl est réversible:

>>> urllib.parse.urlencode(sq)
'a=b&c=d'
phobie
la source
16

urllib.unquote_plus()fait ce que vous voulez. Il remplace les échappements% xx par leur équivalent à un seul caractère et remplace les signes plus par des espaces.

Exemple:

unquote_plus('/%7Ecandidates/?name=john+connolly') 

rendements

'/~candidates/?name=john connolly'.
Andrew Farrell
la source
2
Il a dit qu'il voulait un dict. Votre réponse est donc fausse.
balrok le
4
oui, c'est ce que je cherchais.
Joe