Frage

Wenn ich eine Datei öffnen urllib2 verwenden, etwa so:

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

Gibt es eine einfache Möglichkeit, die Dateinamen andere dann Parsen die Original-URL zu bekommen?

EDIT:. Geändert Openfile urlopen ... nicht sicher, wie das passiert ist

EDIT2: Ich landete mit:

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

Wenn ich nicht irre, sollte dies auch alle möglichen Anfragen Streifen aus.

War es hilfreich?

Lösung

Meinen Sie urllib2.urlopen ?

Sie könnten möglicherweise heben die bestimmt Dateiname , wenn der Server wurde durch Überprüfung remotefile.info()['Content-Disposition'] einen Content-Disposition-Header zu senden, aber da es meiner Meinung nach nur Sie haben analysiert die uRL.

könnten Sie verwenden urlparse.urlsplit, aber wenn Sie keine URLs haben wie bei dem zweiten Beispiel, werden Sie am Ende zu den Dateinamen selbst herausziehen trotzdem:

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

Es könnte aber auch nur dies tun:

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

Andere Tipps

Wenn Sie nur die Dateinamen selbst, unter der Annahme, dass es keine Query-Variablen am Ende wie http://example.com/somedir/somefile.zip?foo=bar dann können Sie os.path.basename für diese verwenden:

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

Einige andere Plakate erwähnten urlparse mit, das wird funktionieren, aber Sie müssen immer noch das führende Verzeichnis aus dem Dateinamen entfernen. Wenn Sie os.path.basename () verwenden, dann müssen Sie nicht befürchten, dass, da sie nur den letzten Teil der URL oder Dateipfad zurückkehrt.

Ich denke, dass „der Dateiname“ nicht sehr gut definiertes Konzept ist, wenn es darum geht, Transfer http. Der Server kann (ist aber nicht erforderlich) ein als „Content-Disposition“ Header zur Verfügung stellen, können Sie versuchen, dass mit remotefile.headers['Content-Disposition'] zu bekommen. Wenn dies nicht gelingt, werden Sie wahrscheinlich die URI selbst zu analysieren haben.

Gerade gesehen, das ich normalerweise tun ..

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

Mit urlsplit ist die sicherste Option:

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

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

Wie auch immer, verwenden Sie die urllib2.urlparse Funktionen:

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

Voila.

Sie können auch beide der beiden besten bewerteten Antworten kombinieren: Mit urllib2.urlparse.urlsplit () den Pfad Teil der URL zu bekommen, und dann os.path.basename für die eigentlichen Dateinamen.

Voll Code wäre:

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

Die os.path.basename Funktion arbeitet nicht nur für die Dateipfade, sondern auch für URLs, so dass Sie nicht manuell die URL selbst analysieren müssen. Außerdem ist es wichtig zu beachten, dass Sie result.url statt der ursprünglichen URL, um Antworten Umleitung zu folgen verwenden sollten:

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

Ich denke, es hängt davon ab, was Sie mit Parsen. Es gibt keine Möglichkeit, den Dateinamen zu erhalten, ohne die URL zu Parsing, das heißt der Remote-Server, den Sie nicht einen Dateinamen nicht geben. Allerdings müssen Sie sich nicht viel zu tun, da ist das urlparse Modul:

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

nicht, dass ich wüsste.

Sie können jedoch analysieren es einfach genug, um wie folgt aus:

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

mit Anfragen, aber man kann es leicht tun mit 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)

Sie können sich wahrscheinlich einfachen regulären Ausdruck hier verwendet werden. 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

Mit PurePosixPath , die nicht in Betrieb ist systemabhängig und Griffe Urls ist anmutig 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, wie es keinen Netzwerkverkehr hier ist oder etwas (das heißt diese URLs nicht überall gehen.) - nur Standard-Parsing-Regeln mit

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 nicht openfile, aber vielleicht hilft immer noch:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top