Jeśli zrobię
url = "http://example.com?p=" + urllib.quote(query)
- To nie koduje
/
się%2F
(łamie OAuth normalizacja) - Nie obsługuje Unicode (zgłasza wyjątek)
Czy jest lepsza biblioteka?
Jeśli zrobię
url = "http://example.com?p=" + urllib.quote(query)
/
się %2F
(łamie OAuth normalizacja)Czy jest lepsza biblioteka?
Odpowiedzi:
Z dokumentów :
urllib.quote(string[, safe])
Zamień znaki specjalne w ciągu za pomocą znaku ucieczki% xx. Litery, cyfry i znaki „_.-” nigdy nie są cytowane. Domyślnie ta funkcja służy do cytowania sekcji ścieżki adresu URL. Opcjonalny bezpieczny parametr określa dodatkowe znaki, które nie powinny być cytowane - jego wartość domyślna to „/”
Oznacza to, że podanie „dla bezpieczeństwa” rozwiąże Twój pierwszy problem:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
O drugiej kwestii, istnieje raport o błędzie o tym tutaj . Najwyraźniej zostało to naprawione w Pythonie 3. Możesz to obejść, kodując jako utf8 w następujący sposób:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Przy okazji spójrz na urlencode
To samo, z wyjątkiem zastąpienia urllib.quote
przez urllib.parse.quote
.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
tym ma do czynienia urllib.quote.
urllib.quote
przeniósł się do urlib.parse.quote
, ponieważ Python3.
urllib.parse.quote
docs
W Pythonie 3 urllib.quote
został przeniesiony urllib.parse.quote
i domyślnie obsługuje Unicode.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
quote
jest raczej ogólnikowa. To może być ładniejszy użyć czegoś jak urlencode: from urllib.parse import quote as urlencode
.
urlencode
w urllib.parse
już, że robi coś zupełnie innego, więc byłbyś lepiej wybierając inną nazwę lub ryzyko poważnie mylące przyszłych czytelników kodzie.
Moja odpowiedź jest podobna do odpowiedzi Paolo.
Myślę, że moduł requests
jest znacznie lepszy. Opiera się na urllib3
. Możesz spróbować:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
requests.utils.quote
jest cienkim opakowaniem kompatybilności urllib.quote
dla Pythona 2 i urllib.parse.quote
Pythona 3
Jeśli używasz django, możesz użyć urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Zauważ, że zmiany w Pythonie od czasu opublikowania tej odpowiedzi oznaczają, że jest to teraz starsze opakowanie. Z kodu źródłowego Django 2.1 dla django.utils.http:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
Lepiej jest użyć urlencode
tutaj. Niewielka różnica dla pojedynczego parametru, ale IMHO sprawia, że kod jest wyraźniejszy. (Wygląda na mylące, gdy widzę funkcję quote_plus
! Szczególnie osoby pochodzące z innych języków)
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/library/urllib.parse.html#urllib.parse.urlencode
quote_plus: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus