次のコードを使用して、インターネットからローカルファイルに大きなファイルをストリーミングします。
fp = open(file, 'wb')
req = urllib2.urlopen(url)
for line in req:
fp.write(line)
fp.close()
これは機能しますが、ダウンロードにかなり時間がかかります。もっと速い方法はありますか? (ファイルが大きいので、メモリに保存したくありません。)
行ごとに作業する理由はありません(小さなチャンクで、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サイズを試して、要件に合った「スイートスポット」を見つけてください。
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)
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でも同様の方法を使用できます...しかし、現在は見つかりません。
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")