nombre del archivo urllib2

Si abro un archivo usando urllib2, así:

remotefile = urllib2.urlopen('http://example.com/somefile.zip') 

¿Hay una forma fácil de obtener el nombre del archivo que no sea analizar la URL original?

EDITAR: se cambió el archivo abierto a urlopen … no estoy seguro de cómo sucedió.

EDIT2: Terminé usando:

 filename = url.split('/')[-1].split('#')[0].split('?')[0] 

A menos que me equivoque, esto también debería eliminar todas las consultas potenciales.

Se refiere a urllib2.urlopen ?

Potencialmente, podría levantar el nombre de archivo deseado si el servidor enviara un encabezado de Disposición de contenido al verificar remotefile.info()['Content-Disposition'] , pero como es, creo que solo tendrá que analizar la url.

Puedes usar urlparse.urlsplit , pero si tienes alguna URL como en el segundo ejemplo, tendrás que sacar el nombre del archivo de todos modos:

 >>> urlparse.urlsplit('http://example.com/somefile.zip') ('http', 'example.com', '/somefile.zip', '', '') >>> urlparse.urlsplit('http://example.com/somedir/somefile.zip') ('http', 'example.com', '/somedir/somefile.zip', '', '') 

También podría hacer esto:

 >>> 'http://example.com/somefile.zip'.split('/')[-1] 'somefile.zip' >>> 'http://example.com/somedir/somefile.zip'.split('/')[-1] 'somefile.zip' 

Si solo desea el nombre del archivo, asumiendo que no hay variables de consulta al final como http://example.com/somedir/somefile.zip?foo=bar, entonces puede usar os.path.basename para esto:

 [user@host]$ python Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04) Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.path.basename("http://example.com/somefile.zip") 'somefile.zip' >>> os.path.basename("http://example.com/somedir/somefile.zip") 'somefile.zip' >>> os.path.basename("http://example.com/somedir/somefile.zip?foo=bar") 'somefile.zip?foo=bar' 

Algunos otros carteles mencionaron el uso de urlparse, que funcionará, pero aún así necesitarías quitar el directorio principal del nombre del archivo. Si usa os.path.basename (), entonces no tiene que preocuparse por eso, ya que solo devuelve la parte final de la URL o la ruta del archivo.

Creo que “el nombre del archivo” no es un concepto muy bien definido cuando se trata de transferencias http. El servidor podría (pero no es obligatorio) proporcionar uno como encabezado de “disposición de contenido”, puede intentar obtener eso con remotefile.headers['Content-Disposition'] . Si esto falla, probablemente tenga que analizar el URI usted mismo.

Acabo de ver esto normalmente lo hago ..

 filename = url.split("?")[0].split("/")[-1] 

Usar urlsplit es la opción más segura:

 url = 'http://example.com/somefile.zip' urlparse.urlsplit(url).path.split('/')[-1] 

¿Se urllib2.urlopen ? No hay ninguna función llamada openfile en el módulo urllib2 .

De todos modos, usa las funciones urllib2.urlparse :

 >>> from urllib2 import urlparse >>> print urlparse.urlsplit('http://example.com/somefile.zip') ('http', 'example.com', '/somefile.zip', '', '') 

Voila

También puede combinar las dos respuestas mejor calificadas: usar urllib2.urlparse.urlsplit () para obtener la parte de la ruta de la URL, y luego os.path.basename para el nombre del archivo real.

El código completo sería:

 >>> remotefile=urllib2.urlopen(url) >>> try: >>> filename=remotefile.info()['Content-Disposition'] >>> except KeyError: >>> filename=os.path.basename(urllib2.urlparse.urlsplit(url).path) 

La función os.path.basename funciona no solo para rutas de archivos, sino también para urls, por lo que no tiene que analizar manualmente la URL. Además, es importante tener en cuenta que debe usar result.url lugar de la url original para seguir las respuestas de redireccionamiento:

 import os import urllib2 result = urllib2.urlopen(url) real_url = urllib2.urlparse.urlparse(result.url) filename = os.path.basename(real_url.path) 

Supongo que depende de lo que quieres decir con el análisis. No hay forma de obtener el nombre de archivo sin analizar la URL, es decir, el servidor remoto no le da un nombre de archivo. Sin embargo, no tienes que hacer mucho por ti mismo, está el módulo urlparse :

 In [9]: urlparse.urlparse('http://example.com/somefile.zip') Out[9]: ('http', 'example.com', '/somefile.zip', '', '', '') 

No que yo sepa.

pero puedes analizarlo con bastante facilidad de la siguiente manera:

url = 'http://example.com/somefile.zip'  imprimir url.split ('/') [- 1]

utilizando solicitudes, pero puede hacerlo fácilmente con urllib (2)

 import requests from urllib import unquote from urlparse import urlparse sample = requests.get(url) if sample.status_code == 200: #has_key not work here, and this help avoid problem with names if filename == False: if 'content-disposition' in sample.headers.keys(): filename = sample.headers['content-disposition'].split('filename=')[-1].replace('"','').replace(';','') else: filename = urlparse(sample.url).query.split('/')[-1].split('=')[-1].split('&')[-1] if not filename: if url.split('/')[-1] != '': filename = sample.url.split('/')[-1].split('=')[-1].split('&')[-1] filename = unquote(filename) 

Probablemente puedas usar expresiones regulares simples aquí. Algo como:

 In [26]: import re In [27]: pat = re.compile('.+[\/\?#=]([\w-]+\.[\w-]+(?:\.[\w-]+)?$)') In [28]: test_set ['http://www.google.com/a341.tar.gz', 'http://www.google.com/a341.gz', 'http://www.google.com/asdasd/aadssd.gz', 'http://www.google.com/asdasd?aadssd.gz', 'http://www.google.com/asdasd#blah.gz', 'http://www.google.com/asdasd?filename=xxxbl.gz'] In [30]: for url in test_set: ....: match = pat.match(url) ....: if match and match.groups(): ....: print(match.groups()[0]) ....: a341.tar.gz a341.gz aadssd.gz aadssd.gz blah.gz xxxbl.gz 

El uso de PurePosixPath que no es un sistema operativo, depende y maneja las urls con gracia es la solución pythonica:

 >>> from pathlib import PurePosixPath >>> path = PurePosixPath('http://example.com/somefile.zip') >>> path.name 'somefile.zip' >>> path = PurePosixPath('http://example.com/nested/somefile.zip') >>> path.name 'somefile.zip' 

Observe que no hay tráfico de red aquí ni nada (es decir, esas direcciones URL no van a ninguna parte), solo se usan las reglas de análisis estándar.

 import os,urllib2 resp = urllib2.urlopen('http://www.example.com/index.html') my_url = resp.geturl() os.path.split(my_url)[1] # 'index.html' 

Esto no es un archivo abierto, pero tal vez todavía ayuda 🙂