web-dev-qa-db-fra.com

Comment coder pour cent les paramètres d'URL en Python?

Si je fais 

url = "http://example.com?p=" + urllib.quote(query)
  1. Il ne code pas / en %2F (casse la normalisation OAuth)
  2. Il ne gère pas Unicode (il lève une exception)

Y a-t-il une meilleure bibliothèque?

246
Paul Tarjan

De la docs :

urllib.quote(string[, safe])

Remplacer les caractères spéciaux dans la chaîne en utilisant le% xx échappement. Lettres, chiffres, et les caractères '_.-' ne sont jamais cité. Par défaut, cette fonction est destiné à citer la section de chemin de l'URL. Le paramètre optionnel safe spécifie des caractères supplémentaires qui ne devrait pas être cité - sa valeur par défaut La valeur est '/'

Cela signifie que passer '' par sécurité résoudra votre premier problème:

>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'

À propos du deuxième numéro, il existe un rapport de bogue à ce sujet ici . Apparemment, il a été corrigé en python 3. Vous pouvez contourner le problème en encodant l'utf8 comme ceci:

>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller

Soit dit en passant, regardez urlencode

Notez que urllib.quote a été déplacé vers urllib.parse.quote en Python3.

336
Nadia Alramli

En Python 3, urllib.quote a été déplacé vers urllib.parse.quote et 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/'
141
Paolo Moretti

Ma réponse est similaire à celle de Paolo.

Je pense que le module requests est bien meilleur. Il est basé sur urllib3. Vous pouvez essayer ceci:

>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
38
Aminah Nuraini

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é. À partir du code source 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)
10
Rick Westera

Il vaut mieux utiliser urlencode ici. Pas beaucoup de différence pour un seul paramètre mais IMHO rend le code plus clair. (Cela semble déroutant de voir une fonction quote_plus! Surtout celles venant d’autres langues)

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

Docs

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

0
balki