Python, função oposta urllib.urlencode


88

Como posso converter dados após o processamento urllib.urlencodepara dict? urllib.urldecodenão existe.

Respostas:


124

Como os docs para urlencodedigamos,

O módulo urlparse fornece as funções parse_qs () e parse_qsl () que são usadas para analisar strings de consulta em estruturas de dados Python.

(Em versões mais antigas do Python, eles estavam no cgimódulo). Então, por exemplo:

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

A diferença óbvia entre o dicionário original de o "round trip" d1é que o último tem (item único, neste caso) listas como valores - isso porque não há garantia de exclusividade nas strings de consulta, e pode ser importante ao seu aplicativo para saber quais valores múltiplos foram dados para cada chave (ou seja, as listas nem sempre serão de um único item ;-).

Como uma alternativa:

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

você pode obter uma sequência de pares (urlencode também aceita tal argumento - neste caso ele preserva a ordem, enquanto no caso dict não há ordem para preservar ;-). Se você sabe que não há "chaves" duplicadas ou não se importa se há, então (como mostrei) você pode ligar dictpara obter um dicionário com valores não listados. Em geral, no entanto, você precisa considerar o que você quer fazer se duplicatas são presentes (Python não decidir que em seu nome ;-).


1
Resposta muito completa. Impressionante!
Hartley Brody

Votação positiva para Python 2, no entanto, Python 3 está todo no urllibmódulo. Veja a resposta @phobie.
openwonk em

18

Código Python 3 para a solução de 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']}

A alternativa:

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

parse_qsl é reversível:

>>> urllib.parse.urlencode(sq)
'a=b&c=d'

16

urllib.unquote_plus()faz o que você quiser. Ele substitui escapes% xx por seus equivalentes de caractere único e substitui os sinais de mais por espaços.

Exemplo:

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

rendimentos

'/~candidates/?name=john connolly'.

2
Ele disse que queria um ditado. Portanto, sua resposta está errada.
Balrok

4
sim, isso é o que eu estava procurando.
Joe
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.