Si lo hago
url = "http://example.com?p=" + urllib.quote(query)
- No codifica
/
a%2F
(rompe la normalización de OAuth) - No maneja Unicode (arroja una excepción)
¿Hay una mejor biblioteca?
Si lo hago
url = "http://example.com?p=" + urllib.quote(query)
/
a %2F
(rompe la normalización de OAuth)¿Hay una mejor biblioteca?
Respuestas:
De los documentos :
urllib.quote(string[, safe])
Reemplace los caracteres especiales en la cadena usando el escape% xx. Las letras, los dígitos y los caracteres '_.-' nunca se citan. De forma predeterminada, 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 citarse; su valor predeterminado es '/'
Eso significa que pasar '' por seguro 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. Puede solucionarlo codificando como utf8 de esta manera:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
Por cierto, eche un vistazo a urlencode
Lo mismo, excepto reemplazar urllib.quote
con urllib.parse.quote
.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
que es lo que trata urllib.quote.
urllib.quote
movido a urlib.parse.quote
, desde Python3.
urllib.parse.quote
docs
En Python 3, urllib.quote
se ha movido urllib.parse.quote
y maneja unicode de manera predeterminada.
>>> from urllib.parse import quote
>>> quote('/test')
'/test'
>>> quote('/test', safe='')
'%2Ftest'
>>> quote('/El Niño/')
'/El%20Ni%C3%B1o/'
quote
es bastante vago como global. Puede ser que sea más agradable de usar algo como urlencode: from urllib.parse import quote as urlencode
.
urlencode
en urllib.parse
ya que hace algo completamente diferente, por lo que sería mejor escoger otro nombre o el riesgo de confundir seriamente los futuros lectores de su código.
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'
requests.utils.quote
es un envoltorio de compatibilidad delgado urllib.quote
para Python 2 y urllib.parse.quote
Python 3
Si está usando 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 desde que se publicó esta respuesta significa que ahora es un contenedor heredado. Del código fuente de 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 solo parámetro, pero en mi humilde opinión, el código es más claro. (¡Parece confuso ver una función quote_plus
! Especialmente las que provienen 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
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