Python、requestsを使ったダウンロード

Twitterでシェア FaceBookでシェア はてなブックマークでシェア

Python - サードパーティ製ライブラリ
2018年11月22日21:15に更新(約21日前)
2018年11月7日20:50に作成(約36日前)

旧ブログ移行記事です。

概要

人に優しいHTTPライブラリrequestsを使った、ファイルダウンロードの方法です。

方法1

標準ライブラリshutilcopyfileobjを使う例です。 何バイトずつ書き込む...みたいな処理もshutilの内部で行ってくれるので、こちらの気にする部分が少なく簡単です。

import os
import shutil
import requests


def download(url):
    file_name = os.path.basename(url)
    res = requests.get(url, stream=True)
    if res.status_code == 200:
        with open(file_name, 'wb') as file:
            res.raw.decode_content = True
            shutil.copyfileobj(res.raw, file)


if __name__ == '__main__':
    url = 'https://narito.ninja/media/316/result.png'
    download(url)

チャンクのサイズを変えたい場合は、オブション引数のlengthを使います。

shutil.copyfileobj(res.raw, file, length=1024)

方法2

requestsの、Response.iter_contentを使い、データを数回に分けて書き込んでいきます。 こちらもメモリがパンクすることはないでしょう。

import os
import requests


def download(url):
    file_name = os.path.basename(url)
    res = requests.get(url, stream=True)
    if res.status_code == 200:
        with open(file_name, 'wb') as file:
            for chunk in res.iter_content(chunk_size=1024):
                file.write(chunk)


if __name__ == '__main__':
    url = 'https://narito.ninja/media/316/result.png'
    download(url)

ダウンロードの場合は、stream=Trueとしましょう。こうすることで、大きいファイルが一気に読み込まれることがなくなります

res = requests.get(url, stream=True)

リクエストが成功した場合です。

if res.status_code == 200:

http://narito.ninja/image.pngなら、file_nameにはimage.pngが
http://narito.ninja/bgm.mp3なら、file_nameにはbgm.mp3が入ります。

file_name = os.path.basename(url)

これは1024バイトにわけて書き込んでいます。

for chunk in res.iter_content(chunk_size=1024):
    file.write(chunk)

ちなみにですが、iter_contentを使わずfor chunk in res:とした場合、128バイトずつになります。これは__iter__メソッドで、return self.iter_content(128)としているためです。なので、無理に'iter_content'を無理に使う必要はなかったりします。

for chunk in res:
    file.write(chunk)
Twitterでシェア FaceBookでシェア はてなブックマークでシェア

記事にコメントする