Подтвердить что ты не робот

Поток больших двоичных файлов с urllib2 в файл

Я использую следующий код для потоковой передачи больших файлов из Интернета в локальный файл:

fp = open(file, 'wb')
req = urllib2.urlopen(url)
for line in req:
    fp.write(line)
fp.close()

Это работает, но он загружается довольно медленно. Есть ли более быстрый способ? (Файлы большие, поэтому я не хочу сохранять их в памяти.)

4b9b3361

Ответ 1

Нет причин работать по строкам (маленькие куски И требует, чтобы Python нашел для вас концы строк!), просто поместите его в большие куски, например:

# from urllib2 import urlopen # Python 2
from urllib.request import urlopen # Python 3

response = urlopen(url)
CHUNK = 16 * 1024
with open(file, 'wb') as f:
    while True:
        chunk = response.read(CHUNK)
        if not chunk:
            break
        f.write(chunk)

Немного экспериментируйте с различными размерами CHUNK, чтобы найти "сладкое пятно" для ваших требований.

Ответ 2

Вы также можете использовать shutil:

import shutil
try:
    from urllib.request import urlopen # Python 3
except ImportError:
    from urllib2 import urlopen # Python 2

def get_large_file(url, file, length=16*1024):
    req = urlopen(url)
    with open(file, 'wb') as fp:
        shutil.copyfileobj(req, fp, length)

Ответ 3

Я использовал модуль mechanize и его метод Browser.retrieve(). В прошлом он занимал 100% процессор и загружал вещи очень медленно, но в некоторых последних версиях исправлена ​​эта ошибка и работает очень быстро.

Пример:

import mechanize
browser = mechanize.Browser()
browser.retrieve('http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.32-rc1.tar.bz2', 'Downloads/my-new-kernel.tar.bz2')

Механизм основан на urllib2, поэтому urllib2 также может иметь похожий метод... но я не могу найти его сейчас.

Ответ 4

Вы можете использовать urllib.retrieve() для загрузки файлов:

Пример:

try:
    from urllib import urlretrieve # Python 2

except ImportError:
    from urllib.request import urlretrieve # Python 3

url = "http://www.examplesite.com/myfile"
urlretrieve(url,"./local_file")