Si je fais
url = "http://example.com?p=" + urllib.quote(query)
- Il n'encode
/
pas%2F
(rompt la normalisation OAuth) - Il ne gère pas Unicode (il lève une exception)
Existe-t-il une meilleure bibliothèque?
Si je fais
url = "http://example.com?p=" + urllib.quote(query)
/
pas %2F
(rompt la normalisation OAuth)Existe-t-il une meilleure bibliothèque?
Réponses:
De la documentation :
urllib.quote(string[, safe])
Remplacez les caractères spéciaux dans la chaîne à l'aide de l'échappement% xx. Les lettres, les chiffres et les caractères '_.-' ne sont jamais cités. Par défaut, cette fonction est destinée à la citation de la section de chemin de l'URL. Le paramètre optionnel sûr spécifie des caractères supplémentaires qui ne doivent pas être cités - sa valeur par défaut est '/'
Cela signifie que le fait de passer '' en toute sécurité résoudra votre premier problème:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
À propos du deuxième problème, il y a un rapport de bogue à ce sujet ici . Apparemment, il a été corrigé en python 3. Vous pouvez le contourner en encodant en utf8 comme ceci:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Au fait, jetez un oeil à urlencode
La même chose, sauf remplacer urllib.quote
par urllib.parse.quote
.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
C'est à cela que traite urllib.quote.
urllib.quote
déplacé vers urlib.parse.quote
, depuis Python3.
urllib.parse.quote
docs
En Python 3, urllib.quote
a été déplacé vers urllib.parse.quote
et il gère unicode par défaut.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
quote
est plutôt vague en tant que global. Il pourrait être plus agréable d'utiliser quelque chose comme urlencode: from urllib.parse import quote as urlencode
.
urlencode
dans urllib.parse
déjà fait quelque chose de complètement différent, vous feriez mieux de choisir un autre nom ou un risque de confusion au sérieux les lecteurs futurs de votre code.
Ma réponse est similaire à la réponse de Paolo.
Je pense que le module requests
est beaucoup mieux. C'est basé sur urllib3
. Vous pouvez essayer ceci:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
requests.utils.quote
est un wrapper de compatibilité mince urllib.quote
pour python 2 et urllib.parse.quote
pour python 3
Si vous utilisez django, vous pouvez utiliser urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Notez que les modifications apportées à Python depuis la publication de cette réponse signifient qu'il s'agit désormais d'un wrapper hérité. Du code source de Django 2.1 pour django.utils.http:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
Il vaut mieux l'utiliser urlencode
ici. Pas beaucoup de différence pour un seul paramètre mais à mon humble avis, le code est plus clair. (Cela semble déroutant de voir une fonction quote_plus
! En particulier ceux provenant d'autres langueurs)
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