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.quotebằng urllib.parse.quote.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","Đó là những gì urllib.quote đang xử lý.
urllib.quotechuyể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.quotevà 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/'
quotekhá 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.
urlencodetrong 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 requestslà 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.quotelà một trình bao bọc tương thích mỏng urllib.quotedành cho python 2 và urllib.parse.quotecho 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