Python, kebalikan dari fungsi urllib.urlencode

88

Bagaimana cara mengonversi data setelah pemrosesan urllib.urlencodeke dikt? urllib.urldecodetidak ada.

Artyom
sumber

Jawaban:

124

Sebagai dokumentasi untuk urlencodemengatakan,

Modul urlparse menyediakan fungsi parse_qs () dan parse_qsl () yang digunakan untuk mengurai string kueri ke dalam struktur data Python.

(Dalam rilis Python yang lebih lama, mereka ada di cgimodul). Jadi, misalnya:

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

Perbedaan nyata antara kamus asli ddan kamus "round-tripped" d1adalah kamus yang terakhir memiliki (item tunggal, dalam hal ini) daftar sebagai nilai - itu karena tidak ada jaminan keunikan dalam string kueri, dan mungkin penting ke aplikasi Anda untuk mengetahui tentang beberapa nilai yang telah diberikan untuk setiap kunci (yaitu, daftar tidak akan selalu menjadi item tunggal ;-).

Sebagai alternatif:

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

Anda bisa mendapatkan urutan pasangan (urlencode menerima argumen seperti itu juga - dalam hal ini mempertahankan urutan, sedangkan dalam kasus dict tidak ada urutan untuk dipertahankan ;-). Jika Anda tahu tidak ada duplikat "kunci", atau tidak peduli jika ada, maka (seperti yang saya tunjukkan) Anda dapat memanggil dictuntuk mendapatkan kamus dengan nilai non-daftar. Secara umum, bagaimanapun, Anda perlu mempertimbangkan apa yang ingin Anda lakukan jika duplikat yang hadir (Python tidak memutuskan bahwa atas nama Anda ;-).

Alex Martelli
sumber
1
Jawaban yang sangat teliti. Hebat!
Hartley Brody
1
Pilih Python 2, namun Python 3 ada di urllibmodul. Lihat jawaban @phobie.
openwonk
19

Kode Python 3 untuk solusi 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']}

Alternatifnya:

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

parse_qsl dapat dibalik:

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

urllib.unquote_plus()melakukan apa yang kamu inginkan. Ini menggantikan% xx pelarian dengan karakter tunggalnya yang setara dan mengganti tanda plus dengan spasi.

Contoh:

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

hasil

'/~candidates/?name=john connolly'.
Andrew Farrell
sumber
2
Dia berkata, dia ingin didik. Jadi jawabanmu salah.
balrok
4
yay, inilah yang saya cari.
Joe