Как я загружаю файл отчетом о выполнении работ с помощью Python, но не предоставляя имя файла.
Я попробовал urllib.urlretrieve, но я, кажется, должен предоставить имя файла для загруженного файла для сохранения как.
Так, например:
Я не хочу предоставлять это:
urllib.urlretrieve("http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US", "/tmp/firefox.exe")
просто это:
urllib.urlretrieve("http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US", "/tmp/")
но если я делаю я получаю эту ошибку:
IOError: [Errno 21] Is a directory: '/tmp'
Также не мог получить имя файла от некоторого Примера URL:
http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US
отредактировано после уточнения вопроса...
urlparse.urlsplit
возьмет открываемый вами url и разделит его на составные части, затем вы можете взять часть path
и использовать последний /
-delimited chunk в качестве имени файла.
import urllib, urlparse
split = urlparse.urlsplit(url)
filename = "/tmp/" + split.path.split("/")[-1]
urllib.urlretrieve(url, filename)
Существует urlopen
, который создает файловый объект, который можно использовать для чтения данных, не сохраняя их в локальном файле:
from urllib2 import urlopen
f = urlopen("http://example.com/")
for line in f:
print len(line)
f.close()
(Я не совсем уверен, что это именно то, вы просите.)
urlgrabber.urlgrab ()
будет использовать базовое имя переданного ему URL в качестве имени файла. Обратите внимание, что он проигнорирует заголовок Content-Disposition
.
URL, который вы указываете, вообще не ссылается на файл. Это перенаправление на веб-страницу, на которой запущен javascript, заставляющий ваш браузер загрузить файл. Фактический адрес, на который был направлен мой браузер (зеркало) с рассматриваемого URL, следующий:
http://mozilla.mirrors.evolva.ro//firefox/releases/3.6.3/win32/en-US/Firefox%20Setup%203.6.3.exe
Я полагаю, что веб-серверы указывают имя файла для загрузки двумя способами:
Content-Disposition
который может указывать другое имя файла для использованияДля файла, который вы хотите загрузить, я думаю, вам нужен только последний сегмент пути URL (но используя фактический URL файла, а не веб-страницу, которая выбирает, какой зеркальный файл использовать). Но для некоторых загрузок вам потребуется получить имя файла из заголовка Content-Disposition
.
Беглый взгляд на javascript на странице firefox показывает:
// 2. Build download.mozilla.org URL out of those vars.
download_url = "http://download.mozilla.org/?product=";
download_url += product + '&os=' + os + '&lang=' + lang;
Так что просто измените свой URL с:
http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US
на
http://download.mozilla.org/?product=firefox-3.6.3&os=win&lang=en-US
Итак, теперь я проверю заголовки, чтобы увидеть, что мы действительно получаем ...
$ curl -I "http://download.mozilla.org/?product=firefox-3.6.3&os=win&lang=en-US"
HTTP/1.1 302 Found
Server: Apache
X-Backend-Server: pp-app-dist09
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private
Content-Type: text/html; charset=UTF-8
Date: Sat, 08 May 2010 21:02:50 GMT
Location: http://mozilla.mirror.ac.za/firefox/releases/3.6.3/win32/en-US/Firefox Setup 3.6.3.exe
Pragma: no-cache
Transfer-Encoding: chunked
Connection: Keep-Alive
Set-Cookie: dmo=10.8.84.200.1273352570769772; path=/; expires=Sun, 08-May-11 21:02:50 GMT
X-Powered-By: PHP/5.1.6
Итак, это на самом деле перенаправление 302, поэтому теперь используйте то, что указано в заголовке Location, в качестве нового URL-адреса, чтобы получить фактический файл. Вам нужно будет выяснить, как сделать запрос и прочитать заголовки самостоятельно (извините, у меня мало времени). После того, как вы проанализируете заголовок местоположения, вы можете вырезать остальную часть местоположения с помощью регулярного выражения, чтобы получить имя файла для сохранения файла:
>>> location = 'http://mozilla.mirror.ac.za/firefox/releases/3.6.3/win32/en-US/Firefox Setup 3.6.3.exe'
>>> re.match('^.*/(.*?)$', location).groups()[0]
'Firefox Setup 3.6.3.exe'
Таким образом, чтобы получить фактическое имя файла, вам нужно будет самостоятельно выполнить 302. Код, необходимый для этого, я оставлю на ваше усмотрение, но, надеюсь, он укажет вам правильное направление.