Имя файла urllib2

Если я открою файл, используя urllib2, вот так:

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

Есть ли простой способ получить имя файла, кроме синтаксического анализа исходного URL?

ИЗМЕНИТЬ: изменил openfile на urlopen... не уверен, как это произошло.

EDIT2: я закончил использование:

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

Если я ошибаюсь, это должно также исключить все потенциальные запросы.

Ответ 1

Вы имели в виду urllib2.urlopen?

Вы могли бы потенциально поднять заданное имя файла, если сервер отправил заголовок Content-Disposition, проверив remotefile.info()['Content-Disposition'], но, как мне кажется, вам просто нужно проанализировать URL-адрес.

Вы можете использовать urlparse.urlsplit, но если у вас есть какие-либо URL-адреса, например, во втором примере, вам все равно придется вытащить имя файла самостоятельно:

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

Можно просто сделать это:

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

Ответ 2

Если вы хотите только имя файла, считая, что в конце нет переменных запроса, например http://example.com/somedir/somefile.zip?foo=bar, вы можете использовать os. path.basename для этого:

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

Некоторые другие плакаты, упомянутые с использованием urlparse, которые будут работать, но вам все равно нужно удалить ведущую директорию из имени файла. Если вы используете os.path.basename(), вам не о чем беспокоиться, поскольку он возвращает только конечную часть URL-адреса или пути к файлу.

Ответ 3

Я думаю, что "имя файла" не является очень четкой концепцией, когда дело касается передачи http. Сервер может (но не обязательно) предоставлять его в качестве заголовка "content-disposition", вы можете попытаться получить его с помощью remotefile.headers['Content-Disposition']. Если это не удается, вам, вероятно, придется самостоятельно проанализировать URI.

Ответ 4

Просто увидел это, как обычно.

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

Ответ 5

Использование urlsplit - самый безопасный вариант:

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

Ответ 6

Вы имеете в виду urllib2.urlopen? В модуле urllib2 нет функции, называемой openfile.

В любом случае, используйте функции urllib2.urlparse:

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

Voila.

Ответ 7

Функция os.path.basename работает не только для путей к файлам, но также и для URL-адресов, поэтому вам не нужно вручную вручную анализировать URL-адрес. Кроме того, важно отметить, что вы должны использовать result.url вместо исходного URL, чтобы следить за ответами перенаправления:

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

Ответ 8

Вы также можете объединить оба из двух наилучших ответов: Используя urllib2.urlparse.urlsplit(), чтобы получить путь к URL-адресу, а затем os.path.basename для фактического имени файла.

Полный код:

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

Ответ 9

Я думаю, это зависит от того, что вы подразумеваете под разбором. Невозможно получить имя файла без разбора URL-адреса, т.е. Удаленный сервер не даст вам имя файла. Однако вам не нужно много делать, там модуль urlparse:

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

Ответ 10

Не знаю, что я знаю.

но вы можете легко разобрать его следующим образом:


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

Ответ 11

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

os.path.split(my_url)[1]

# 'index.html'

Это не openfile, но, возможно, все еще помогает:)

Ответ 12

используя запросы, но вы можете сделать это легко с помощью 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)

Ответ 13

Вы, вероятно, можете использовать простое регулярное выражение здесь. Что-то вроде:

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

Ответ 14

Используя PurePosixPath, который не работает зависящим от системы и грамотно обрабатывает URL-адреса, является питоновым решением:

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

Обратите внимание, что здесь нет сетевого трафика (т.е. эти URL-адреса никуда не отправляются) - просто используя стандартные правила синтаксического анализа.