Имя файла 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-адреса никуда не отправляются) - просто используя стандартные правила синтаксического анализа.