Domanda

Se apro un file usando urllib2, in questo modo:

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

Esiste un modo semplice per ottenere il nome del file oltre all'analisi dell'URL originale?

EDIT: cambiato openfile in urlopen ... non sono sicuro di come sia successo.

EDIT2: ho finito per usare:

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

A meno che non mi sbagli, questo dovrebbe eliminare anche tutte le potenziali query.

È stato utile?

Soluzione

Intendevi urllib2.urlopen ?

Potresti potenzialmente sollevare il previsto nomefile se il server stava inviando un'intestazione Content-Disposition controllando remotefile.info () ['Content-Disposition' ] , ma credo che dovrai solo analizzare l'URL.

Potresti usare urlparse.urlsplit , ma se hai qualche URL come nel secondo esempio, finirai per dover estrarre comunque il nome del file:

>>> 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', '', '')

Potrebbe anche fare questo:

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

Altri suggerimenti

Se vuoi solo il nome del file stesso, supponendo che alla fine non ci siano variabili di query come http://example.com/somedir/somefile.zip?foo=bar quindi puoi usare os.path.basename per questo:

[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'

Alcuni altri poster citati usando urlparse, che funzionerà, ma dovrai comunque rimuovere la directory principale dal nome del file. Se usi os.path.basename (), non devi preoccupartene, poiché restituisce solo la parte finale dell'URL o del percorso del file.

Penso che " il nome del file " non è un concetto molto ben definito quando si tratta di trasferimenti http. Il server potrebbe (ma non è tenuto a) fornirne uno come "content-disposition" intestazione, puoi provare a ottenerlo con remotefile.headers ['Content-Disposition'] . Se fallisce, probabilmente devi analizzare tu stesso l'URI.

Ho appena visto questo che faccio normalmente ..

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

L'uso di urlsplit è l'opzione più sicura:

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

Intendi urllib2.urlopen ? Non esiste una funzione chiamata openfile nel modulo urllib2 .

Utilizza comunque le funzioni urllib2.urlparse :

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

Voila.

Puoi anche combinare entrambe le due risposte più votate: Utilizzo di urllib2.urlparse.urlsplit () per ottenere la parte del percorso dell'URL, quindi os.path.basename per il nome file effettivo.

Il codice completo sarebbe:

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

La funzione os.path.basename funziona non solo per i percorsi dei file, ma anche per gli URL, quindi non è necessario analizzare manualmente l'URL. Inoltre, è importante notare che è necessario utilizzare result.url anziché l'URL originale per seguire le risposte di reindirizzamento:

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

Suppongo che dipenda da cosa intendi per analisi. Non è possibile ottenere il nome file senza analizzare l'URL, ovvero il server remoto non fornisce un nome file. Tuttavia, non devi fare molto da solo, c'è il modulo urlparse :

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

non che io sappia.

ma puoi analizzarlo abbastanza facilmente in questo modo:

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

usando le richieste, ma puoi farlo facilmente 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)

Probabilmente puoi usare una semplice espressione regolare qui. Qualcosa del tipo:

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

Utilizzo di PurePosixPath che non è un sistema operativo & # 8212; dipendente e gestisce gli URL con garbo è la soluzione pitonica:

>>> 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'

Nota come non c'è traffico di rete qui o altro (ovvero, quegli URL non vanno da nessuna parte) - semplicemente usando le regole di analisi standard.

import os,urllib2
resp = urllib2.urlopen('http://www.example.com/index.html')
my_url = resp.geturl()

os.path.split(my_url)[1]

# 'index.html'

Questo non è un file aperto, ma forse aiuta ancora :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top