Python, przeciwna funkcja urllib.urlencode

88

Jak mogę przekonwertować dane po przetworzeniu urllib.urlencodena dyktowanie? urllib.urldecodenie istnieje.

Artem
źródło

Odpowiedzi:

124

Jak docs do urlencodepowiedzenia,

Moduł urlparse udostępnia funkcje parse_qs () i parse_qsl (), które są używane do analizowania ciągów zapytań w struktury danych Pythona.

(W starszych wersjach Pythona znajdowały się w cgimodule). Na przykład:

>>> 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']}

Oczywistą różnicą między oryginalnym słownikiem da słownikiem „w obie strony” d1jest to, że ten drugi ma (w tym przypadku pojedynczy element) listy jako wartości - to dlatego, że nie ma gwarancji unikalności w ciągach zapytań i może to być ważne do swojej aplikacji, aby dowiedzieć się, jakie wartości zostały podane dla każdego klucza (to znaczy, że listy nie zawsze będą zawierały pojedyncze pozycje ;-).

Jako alternatywa:

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

można uzyskać ciąg par (urlencode też akceptuje taki argument - w tym przypadku zachowuje porządek, podczas gdy w przypadku dyktowania nie ma porządku do zachowania ;-). Jeśli wiesz, że nie ma zduplikowanych „kluczy” lub nie obchodzi cię, czy istnieją, to (jak pokazałem) możesz wywołać dictsłownik z wartościami spoza listy. Ogólnie jednak musisz zastanowić się, co chcesz zrobić, jeśli istnieją duplikaty (Python nie decyduje o tym w Twoim imieniu ;-).

Alex Martelli
źródło
1
Bardzo dokładna odpowiedź. Niesamowite!
Hartley Brody
1
Głos za Pythonem 2, jednak Python 3 jest w całości w urllibmodule. Zobacz odpowiedź @phobie.
openwonk
19

Kod Python 3 dla rozwiązania Alexa:

>>> 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']}

Alternatywa:

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

parse_qsl jest odwracalne:

>>> urllib.parse.urlencode(sq)
'a=b&c=d'
phobie
źródło
16

urllib.unquote_plus()robi co chcesz. Zastępuje znaki ucieczki% xx ich jednoznakowym odpowiednikiem i zastępuje znaki plus spacjami.

Przykład:

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

plony

'/~candidates/?name=john connolly'.
Andrew Farrell
źródło
2
Powiedział, że chciał dyktować. Więc twoja odpowiedź jest błędna.
balrok
4
tak, to jest to, czego szukałem.
Joe