it-swarm.com.de

urllib2 Dateiname

Wenn ich eine Datei mit urllib2 öffne, wie folgt:

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

Gibt es eine einfache Möglichkeit, den Dateinamen anders als die ursprüngliche URL zu analysieren?

EDIT: openfile in urlopen geändert ... nicht sicher, wie das passiert ist.

EDIT2: Ich habe am Ende verwendet:

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

Wenn ich mich nicht irre, sollte dies auch alle möglichen Fragen ausschließen.

31
defrex

Meinten Sie urllib2.urlopen ?

Sie könnten möglicherweise den beabsichtigten filename heben, wenn der Server einen Content-Disposition-Header gesendet hat, indem Sie remotefile.info()['Content-Disposition'] überprüfen. Da dies jedoch der Fall ist, müssen Sie nur die URL analysieren.

Sie könnten urlparse.urlsplit verwenden, aber wenn Sie URLs wie im zweiten Beispiel haben, müssen Sie den Dateinamen trotzdem selbst herausholen:

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

Könnte auch das einfach tun:

>>> 'http://example.com/somefile.Zip'.split('/')[-1]
'somefile.Zip'
>>> 'http://example.com/somedir/somefile.Zip'.split('/')[-1]
'somefile.Zip'
49
Jonny Buchanan

Wenn Sie nur den Dateinamen selbst haben möchten, vorausgesetzt, dass am Ende keine Abfragevariablen wie http://example.com/somedir/somefile.zip?foo=bar vorhanden sind, können Sie os.path.basename für verwenden diese: 

[[email protected]]$ 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'

Einige andere Poster verwenden urlparse, was funktionieren wird, aber Sie müssen trotzdem das führende Verzeichnis vom Dateinamen entfernen. Wenn Sie os.path.basename () verwenden, müssen Sie sich nicht darum kümmern, da nur der letzte Teil der URL oder des Dateipfads zurückgegeben wird.

13
Jay

Ich denke, dass "der Dateiname" kein sehr gut definiertes Konzept ist, wenn es um HTTP-Übertragungen geht. Der Server kann (muss aber nicht) einen Header als "content-disposition" -Header bereitstellen. Sie können versuchen, dies mit remotefile.headers['Content-Disposition'] zu erhalten. Wenn dies fehlschlägt, müssen Sie den URI wahrscheinlich selbst analysieren.

7
Rafał Dowgird

Ich habe gerade das gesehen, was ich normalerweise mache ..

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

Die Verwendung von urlsplit ist die sicherste Option:

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

Meinen Sie urllib2.urlopen? Es gibt keine Funktion namens openfile im urllib2-Modul.

Verwenden Sie trotzdem die urllib2.urlparse-Funktionen:

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

Voila.

2
Dan Lenski

Die Funktion os.path.basename funktioniert nicht nur für Dateipfade, sondern auch für URLs, sodass Sie die URL nicht manuell analysieren müssen. Beachten Sie außerdem, dass Sie anstelle der ursprünglichen URL result.url verwenden sollten, um den Umleitungsantworten zu folgen:

import os
import urllib2
result = urllib2.urlopen(url)
real_url = urllib2.urlparse.urlparse(result.url)
filename = os.path.basename(real_url.path)
2
Régis B.

Sie können auch die beiden am besten bewerteten Antworten kombinieren: Verwenden Sie urllib2.urlparse.urlsplit (), um den Pfadteil der URL zu erhalten, und dann os.path.basename für den tatsächlichen Dateinamen.

Der vollständige Code wäre:

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

Ich denke, es kommt darauf an, was Sie mit Parsing meinen. Es gibt keine Möglichkeit, den Dateinamen zu ermitteln, ohne die URL zu analysieren, d. H. Der Remote-Server gibt keinen Dateinamen an. Sie müssen jedoch nicht viel selbst tun, es gibt das Modul urlparse:

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

nicht, dass ich davon Wüste.

aber Sie können es einfach genug so analysieren:

url = 'http://example.com/somefile.Zip'
print url.split ('/') [- 1] 
 </ pre> </ code>

1
Corey Goldberg

Die Verwendung von PurePosixPath , das nicht vom Betriebssystem abhängig ist und URLs ordnungsgemäß verarbeitet, ist die Pythonic-Lösung:

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

Beachten Sie, dass es hier keinen Netzwerkverkehr gibt oder etwas (d. H. Diese URLs gehen nicht irgendwo hin) - nur unter Verwendung von Standard-Parsing-Regeln.

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

os.path.split(my_url)[1]

# 'index.html'

Dies ist kein openfile, aber vielleicht hilft es trotzdem :)

0
user15453

Sie können hier wahrscheinlich einen einfachen regulären Ausdruck verwenden. So etwas wie:

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
0
Vovan Kuznetsov

anfragen verwenden, aber mit urllib ist das problemlos möglich (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)
0
DoomedRaven