Python ฟังก์ชันตรงข้าม urllib.urlencode


89

ฉันจะแปลงข้อมูลหลังจากประมวลผลurllib.urlencodeเป็น dict ได้อย่างไร urllib.urldecodeไม่ได้อยู่.

คำตอบ:


126

ในฐานะที่เป็นเอกสารสำหรับการurlencodeพูด

โมดูล urlparse จัดเตรียมฟังก์ชัน parse_qs () และ parse_qsl () ซึ่งใช้เพื่อแยกวิเคราะห์สตริงการสืบค้นลงในโครงสร้างข้อมูล Python

(ใน Python รุ่นเก่ากว่าจะอยู่ในcgiโมดูล) ตัวอย่างเช่น:

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

ความแตกต่างที่เห็นได้ชัดระหว่างพจนานุกรมเดิมdและ "รอบสะดุด" คนหนึ่งd1เป็นที่หลังมี (รายการเดียวในกรณีนี้) รายการเป็นค่า - นั่นเป็นเพราะไม่มีการรับประกันเอกลักษณ์ในสตริงแบบสอบถามและมันอาจจะเป็นสิ่งสำคัญ ไปยังแอปของคุณเพื่อทราบว่ามีการกำหนดค่าหลายค่าสำหรับแต่ละคีย์ (นั่นคือรายการจะไม่เป็นรายการเดียวเสมอไป ;-)

เป็นทางเลือก:

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

คุณสามารถหาลำดับคู่ได้ (urlencode ยอมรับอาร์กิวเมนต์เช่นกัน - ในกรณีนี้จะรักษาคำสั่งในขณะที่ในกรณี dict ไม่มีคำสั่งให้เก็บรักษา ;-) หากคุณทราบว่าไม่มี "คีย์" ที่ซ้ำกันหรือไม่สนใจว่าจะมีหรือไม่ (ตามที่ฉันแสดง) คุณสามารถเรียกdictพจนานุกรมที่มีค่าที่ไม่ใช่รายการได้ อย่างไรก็ตามโดยทั่วไปคุณต้องพิจารณาว่าคุณต้องการทำอะไรหากมีรายการที่ซ้ำกันอยู่ (Python ไม่ได้ตัดสินใจในนามของคุณ ;-)


1
คำตอบอย่างละเอียดมาก สุดยอด!
Hartley Brody

1
โหวตให้ Python 2 อย่างไรก็ตาม Python 3 ทั้งหมดอยู่ในurllibโมดูล ดูคำตอบของ @phobie
openwonk

19

รหัส Python 3สำหรับโซลูชันของ 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']}

ทางเลือก:

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

parse_qsl สามารถย้อนกลับได้:

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

16

urllib.unquote_plus()ทำในสิ่งที่คุณต้องการ มันจะแทนที่% xx Escape ด้วยอักขระตัวเดียวที่เทียบเท่าและแทนที่เครื่องหมายบวกด้วยช่องว่าง

ตัวอย่าง:

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

ผลตอบแทน

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

2
เขาบอกว่าเขาต้องการคำสั่ง ดังนั้นคำตอบของคุณจึงผิด
balrok

4
ใช่นี่คือสิ่งที่ฉันกำลังมองหา
โจ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.