使用urllib2将大文件流式传输到文件中

57 投票
4 回答
60437 浏览
提问于 2025-04-15 14:48

我用以下代码从互联网下载大文件到本地:

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

这个方法可以用,但下载速度比较慢。有没有更快的方法?(因为文件很大,所以我不想把它们放在内存里。)

4 个回答

6

我以前用过 mechanize 这个模块,还有它的 Browser.retrieve() 方法。之前这个方法会占用100%的CPU,下载东西非常慢,但最近的一个更新修复了这个问题,现在运行得很快。

举个例子:

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

Mechanize 是基于 urllib2 的,所以 urllib2 也可能有类似的方法……不过我现在找不到任何相关的方法。

70

你还可以使用 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)
118

没有必要一行一行地处理(这样做太麻烦了,而且还得用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)

可以尝试不同的块大小,找到最适合你需求的那个“最佳大小”。

撰写回答