Nếu tôi làm
url = "http://example.com?p=" + urllib.quote(query)
- Nó không mã hóa
/
thành%2F
(phá vỡ chuẩn hóa OAuth) - Nó không xử lý Unicode (nó ném một ngoại lệ)
Có một thư viện tốt hơn?
Nếu tôi làm
url = "http://example.com?p=" + urllib.quote(query)
/
thành %2F
(phá vỡ chuẩn hóa OAuth)Có một thư viện tốt hơn?
Câu trả lời:
Từ các tài liệu :
urllib.quote(string[, safe])
Thay thế các ký tự đặc biệt trong chuỗi bằng cách sử dụng% xx thoát. Chữ cái, chữ số và ký tự '_.-' không bao giờ được trích dẫn. Theo mặc định, chức năng này được dành để trích dẫn phần đường dẫn của URL. Tham số an toàn tùy chọn chỉ định các ký tự bổ sung không nên trích dẫn - giá trị mặc định của nó là '/'
Điều đó có nghĩa là vượt qua '' cho an toàn sẽ giải quyết vấn đề đầu tiên của bạn:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
Về vấn đề thứ hai, có một báo cáo lỗi về nó ở đây . Rõ ràng nó đã được sửa trong python 3. Bạn có thể khắc phục nó bằng cách mã hóa dưới dạng utf8 như thế này:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Nhân tiện, hãy xem urlencode
Tương tự, ngoại trừ thay thế urllib.quote
bằng urllib.parse.quote
.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
Đó là những gì urllib.quote đang xử lý.
urllib.quote
chuyển đến urlib.parse.quote
, kể từ Python3.
urllib.parse.quote
tài liệu
Trong Python 3, urllib.quote
đã được chuyển đến urllib.parse.quote
và nó xử lý unicode theo mặc định.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
quote
khá mơ hồ như toàn cầu. Nó có thể đẹp hơn để sử dụng một cái gì đó như urlencode : from urllib.parse import quote as urlencode
.
urlencode
trong urllib.parse
đã có làm điều gì đó hoàn toàn khác nhau, vì vậy bạn muốn được tốt hơn chọn một tên khác hoặc có nguy cơ gây nhầm lẫn nghiêm trọng độc giả tương lai của mã của bạn.
Câu trả lời của tôi tương tự như câu trả lời của Paolo.
Tôi nghĩ rằng mô-đun requests
là tốt hơn nhiều. Nó dựa trên urllib3
. Bạn có thể thử điều này:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
requests.utils.quote
là một trình bao bọc tương thích mỏng urllib.quote
dành cho python 2 và urllib.parse.quote
cho python 3
Nếu bạn đang sử dụng django, bạn có thể sử dụng urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Lưu ý rằng các thay đổi đối với Python vì câu trả lời này đã được xuất bản có nghĩa là đây là một trình bao bọc kế thừa. Từ mã nguồn Django 2.1 cho django.utils.http:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
Nó là tốt hơn để sử dụng urlencode
ở đây. Không có nhiều khác biệt cho tham số đơn nhưng IMHO làm cho mã rõ ràng hơn. (Có vẻ khó hiểu khi thấy một chức năng quote_plus
! Đặc biệt là những người đến từ các nhóm khác)
In [21]: query='lskdfj/sdfkjdf/ksdfj skfj'
In [22]: val=34
In [23]: from urllib.parse import urlencode
In [24]: encoded = urlencode(dict(p=query,val=val))
In [25]: print(f"http://example.com?{encoded}")
http://example.com?p=lskdfj%2Fsdfkjdf%2Fksdfj+skfj&val=34
urlencode: https://docs.python.org/3/l Library / urllib.parse.html # urllib.parse.urlencode
quote_plus: https://docs.python.org/3/l Library / urllib.parse.html # urllib.parse.quote_plus