имя файла urllib2 - PullRequest
       41

имя файла urllib2

31 голосов
/ 02 октября 2008

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

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

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

РЕДАКТИРОВАТЬ: изменил openfile на urlopen ... не знаю, как это произошло.

РЕДАКТИРОВАТЬ 2: я закончил с использованием:

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

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

Ответы [ 14 ]

49 голосов
/ 02 октября 2008

Вы имели в виду 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'
13 голосов
/ 02 октября 2008

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

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

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

7 голосов
/ 02 октября 2008

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

5 голосов
/ 20 марта 2015

Только что видел, что я обычно делаю ..

filename = url.split("?")[0].split("/")[-1]
4 голосов
/ 01 апреля 2013

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

url = 'http://example.com/somefile.zip'
urlparse.urlsplit(url).path.split('/')[-1]
2 голосов
/ 28 апреля 2016

Вы также можете объединить оба из двух лучших ответов: Использование 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)
2 голосов
/ 11 мая 2015

Функция 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)
2 голосов
/ 02 октября 2008

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

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

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

Вуаля.

1 голос
/ 02 октября 2008

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

но вы можете разобрать это достаточно просто, как это:

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

1 голос
/ 02 октября 2008

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

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