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.quotepar urllib.parse.quote.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","C'est à cela que traite urllib.quote.
urllib.quotedéplacé vers urlib.parse.quote, depuis Python3.
urllib.parse.quote docs
En Python 3, urllib.quotea été déplacé vers urllib.parse.quoteet 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/'
quoteest 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.
urlencodedans urllib.parsedé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 requestsest 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.quoteest un wrapper de compatibilité mince urllib.quotepour python 2 et urllib.parse.quotepour 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 urlencodeici. 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