¿Cómo en el porcentaje de parámetros de URL en Python?
Pregunta
Si lo hago
url = "http://example.com?p=" + urllib.quote(query)
- No codifica
/
a%2F
(Rompe la normalización de OAuth) - No maneja unicode (lanza una excepción)
¿Hay una mejor biblioteca?
Solución
Desde el documentos:
urllib.quote(string[, safe])
Reemplace los caracteres especiales en la cadena usando el %XX de escape. Las letras, los dígitos y los caracteres '_.-' nunca se citan. Por defecto, esta función está destinada a citar la sección de ruta de la URL. El parámetro seguro opcional especifica caracteres adicionales que no deben cotizarse, Su valor predeterminado es '/'
Eso significa que pasar "para SAFE resolverá su primer problema:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
Sobre el segundo problema, hay un informe de error al respecto aquí. Aparentemente se solucionó en Python 3. Puedes solucionarlo codificando como UTF8 como este:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Por cierto, eche un vistazo a urlencode
Nota que urllib.quote
trasladado a urllib.parse.quote
en python3
Otros consejos
En Python 3, urllib.quote
ha sido trasladado a urllib.parse.quote
y maneja Unicode de forma predeterminada.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
Mi respuesta es similar a la respuesta de Paolo.
Creo que el módulo requests
es mucho mejor. Se basa en urllib3
. Puedes probar esto:
>>> from requests.utils import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
Si está utilizando Django, puede usar Urlquote:
>>> from django.utils.http import urlquote
>>> urlquote(u"Müller")
u'M%C3%BCller'
Tenga en cuenta que los cambios en Python, ya que se publicó esta respuesta, significa que ahora es un envoltorio heredado. Desde el código fuente Django 2.1 para django.utils.http:
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
(was used for unicode handling on Python 2)
Es mejor usar urlencode
aquí. No hay mucha diferencia para un parámetro único, pero en mi humilde opinión deja el código más claro. (Parece confuso ver una función quote_plus
! Especialmente aquellos que vienen de otros idiomas)
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
Documentos
urlencode: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
cita_plus: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus