Как загрузить файл с помощью Python 'более умным' способом?

Добавьте деталь: теперь при каждой перезагрузке она переходит с ветки 1.2 на ветку 2 ... это может быть до "session_destroy ();" ??? В этом случае я не знаю, как сбросить сеанс после его истечения.

67
задан kender 14 May 2009 в 08:21
поделиться

4 ответа

Подобные сценарии загрузки обычно добавляют заголовок, сообщающий пользовательскому агенту, как назвать файл:

Content-Disposition: attachment; filename="the filename.ext"

Если вы можете получить этот заголовок, вы можете получить правильное имя файла.

Есть еще один поток , который предлагает небольшой фрагмент кода для Content-Disposition -grabbing.

remotefile = urllib2.urlopen('http://example.com/somefile.zip')
remotefile.info()['Content-Disposition']
41
ответ дан 24 November 2019 в 14:41
поделиться

Основываясь на комментариях и ответе @Oli, я сделал следующее решение:

from os.path import basename
from urlparse import urlsplit

def url2name(url):
    return basename(urlsplit(url)[2])

def download(url, localFileName = None):
    localName = url2name(url)
    req = urllib2.Request(url)
    r = urllib2.urlopen(req)
    if r.info().has_key('Content-Disposition'):
        # If the response has Content-Disposition, we take file name from it
        localName = r.info()['Content-Disposition'].split('filename=')[1]
        if localName[0] == '"' or localName[0] == "'":
            localName = localName[1:-1]
    elif r.url != url: 
        # if we were redirected, the real file name we take from the final URL
        localName = url2name(r.url)
    if localFileName: 
        # we can force to save the file as specified name
        localName = localFileName
    f = open(localName, 'wb')
    f.write(r.read())
    f.close()

Имя файла берется из Content-Disposition; если его нет, использует имя файла из URL-адреса (если произошло перенаправление, принимается во внимание конечный URL-адрес).

35
ответ дан 24 November 2019 в 14:41
поделиться

Сочетание многое вышеизложенного, вот более питоновый раствор:

import urllib2
import shutil
import urlparse
import os

def download(url, fileName=None):
    def getFileName(url,openUrl):
        if 'Content-Disposition' in openUrl.info():
            # If the response has Content-Disposition, try to get filename from it
            cd = dict(map(
                lambda x: x.strip().split('=') if '=' in x else (x.strip(),''),
                openUrl.info()['Content-Disposition'].split(';')))
            if 'filename' in cd:
                filename = cd['filename'].strip("\"'")
                if filename: return filename
        # if no filename was found above, parse it out of the final URL.
        return os.path.basename(urlparse.urlsplit(openUrl.url)[2])

    r = urllib2.urlopen(urllib2.Request(url))
    try:
        fileName = fileName or getFileName(url,r)
        with open(fileName, 'wb') as f:
            shutil.copyfileobj(r,f)
    finally:
        r.close()
23
ответ дан 24 November 2019 в 14:41
поделиться

2 Кендер :

if localName[0] == '"' or localName[0] == "'":
    localName = localName[1:-1]

это небезопасно - веб-сервер может передавать имя в неправильном формате как ["file.ext] или [file .ext '] или даже быть пустым, и localName [0] вызовет исключение. Правильный код может выглядеть так:

localName = localName.replace('"', '').replace("'", "")
if localName == '':
    localName = SOME_DEFAULT_FILE_NAME
1
ответ дан 24 November 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: