¿Cómo puedo normalizar una URL en python?
normalization normalize (8)
Me gustaría saber si normalizo una URL en Python.
Por ejemplo, si tengo una cadena de URL como: " http://www.example.com/foo goo / bar.html"
Necesito una biblioteca en python que transformará el espacio adicional (o cualquier otro carácter no normalizado) en una URL adecuada.
Debido a que esta página es un resultado superior para las búsquedas de Google sobre el tema, creo que vale la pena mencionar algún trabajo que se haya realizado sobre la normalización de URL con Python que vaya más allá de urlencoding de caracteres espaciales. Por ejemplo, tratar con puertos predeterminados, carácteres de caracteres, ausencia de barras diagonales, etc.
Cuando se estaba desarrollando el formato de sindicación de Atom, hubo un debate sobre cómo normalizar las URL en formato canónico; esto está documentado en el artículo PaceCanonicalIds en la wiki de Atom / Pie. Ese artículo proporciona algunos buenos casos de prueba.
Creo que uno de los resultados de esta discusión fue la biblioteca urlnorm.py Mark Nottingham, que he utilizado con buenos resultados en un par de proyectos. Sin embargo, esa secuencia de comandos no funciona con la URL dada en esta pregunta. Así que una mejor opción podría ser la versión de urlnorm.py de Sam Ruby , que maneja esa URL, y todos los casos de prueba antes mencionados de la wiki de Atom.
Me encuentro con un problema así: solo necesito citar el espacio.
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;''@()*[]")
ayuda, pero es demasiado complicado.
Así que utilicé una forma simple: url = url.replace('' '', ''%20'')
, no es perfecto, pero es la manera más simple y funciona para esta situación.
Solo FYI, urlnorm se ha mudado a github: http://gist.github.com/246089
Válido para Python 3.5:
import urllib.parse
urllib.parse.quote([your_url], "/./_-:")
ejemplo:
import urllib.parse
print(urllib.parse.quote("http://www.example.com/foo goo/bar.html", "/./_-:"))
el resultado será http://www.example.com/foo%20goo/bar.html
Fuente: https://docs.python.org/3.5/library/urllib.parse.html?highlight=quote#urllib.parse.quote
use urllib.quote
o urllib.quote_plus
De la documentación de urllib :
quote (string [, safe])
Reemplaza los caracteres especiales en cadena usando el escape "% xx". Las letras, los dígitos y los caracteres "_.-" nunca se citan. El parámetro de seguridad opcional especifica caracteres adicionales que no se deben citar: su valor predeterminado es ''/''.
Ejemplo:
quote(''/~connolly/'')
produce''/%7econnolly/''
.quote_plus (string [, safe])
Como quote (), pero también reemplaza espacios por signos más, según se requiera para citar valores de formularios HTML. Los signos más en la cadena original se escapan a menos que estén incluidos en la caja fuerte. Tampoco tiene un valor por defecto seguro para ''/''.
EDITAR: Usar urllib.quote o urllib.quote_plus en toda la URL lo destruirá, como señala @ ΤΖΩΤΖΙΟΥ:
>>> quoted_url = urllib.quote(''http://www.example.com/foo goo/bar.html'')
>>> quoted_url
''http%3A//www.example.com/foo%20goo/bar.html''
>>> urllib2.urlopen(quoted_url)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:/python25/lib/urllib2.py", line 124, in urlopen
return _opener.open(url, data)
File "c:/python25/lib/urllib2.py", line 373, in open
protocol = req.get_type()
File "c:/python25/lib/urllib2.py", line 244, in get_type
raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: http%3A//www.example.com/foo%20goo/bar.html
@ ΤΖΩΤΖΙΟΥ proporciona una función que usa urlparse.urlparse y urlparse.urlunparse para analizar la url y codificar solo la ruta. Esto puede ser más útil para usted, aunque si está construyendo la URL de un protocolo y un host conocidos, pero con una ruta sospechosa, probablemente podría hacer lo mismo para evitar urlparse y simplemente citar la parte sospechosa de la URL, concatenando con partes seguras conocidas.
Solución real en Python 2.7 para ese problema
La solución correcta fue:
# percent encode url, fixing lame server errors for e.g, like space
# within url paths.
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;''@()*[]")
Para obtener más información, consulte el Issue 918368: "urllib no corrige las URL devueltas por el servidor"
Eche un vistazo a este módulo: werkzeug.utils . (ahora en werkzeug.urls
)
La función que está buscando se llama "url_fix" y funciona así:
>>> url_fix(u''http://de.wikipedia.org/wiki/Elf (Begriffsklärung)'')
''http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29''
Se implementa en Werkzeug de la siguiente manera:
import urllib
import urlparse
def url_fix(s, charset=''utf-8''):
"""Sometimes you get an URL by a user that just isn''t a real
URL because it contains unsafe characters like '' '' and so on. This
function can fix some of the problems in a similar way browsers
handle data entered by the user:
>>> url_fix(u''http://de.wikipedia.org/wiki/Elf (Begriffsklärung)'')
''http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29''
:param charset: The target charset for the URL if the url was
given as unicode string.
"""
if isinstance(s, unicode):
s = s.encode(charset, ''ignore'')
scheme, netloc, path, qs, anchor = urlparse.urlsplit(s)
path = urllib.quote(path, ''/%'')
qs = urllib.quote_plus(qs, '':&='')
return urlparse.urlunsplit((scheme, netloc, path, qs, anchor))
import urlparse, urllib
def myquote(url):
parts= urlparse.urlparse(url)
return urlparse.urlunparse(parts[:2] + urllib.quote(parts[2]) + parts[3:])
Esto cita solo el componente de ruta.
De lo contrario, podría hacer: urllib.quote(url, safe=":/")