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.quoteprzez urllib.parse.quote.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","tym ma do czynienia urllib.quote.
urllib.quoteprzeniósł się do urlib.parse.quote, ponieważ Python3.
urllib.parse.quote docs
W Pythonie 3 urllib.quotezostał przeniesiony urllib.parse.quotei 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/'
quotejest raczej ogólnikowa. To może być ładniejszy użyć czegoś jak urlencode: from urllib.parse import quote as urlencode.
urlencodew urllib.parsejuż, ż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ł requestsjest znacznie lepszy. Opiera się na urllib3. Możesz spróbować:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
requests.utils.quotejest cienkim opakowaniem kompatybilności urllib.quotedla Pythona 2 i urllib.parse.quotePythona 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ć urlencodetutaj. 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