ひろこま Hack Log

プログラミングや機械学習などの知識を記録・共有します

Google Driveから巨大ファイルをダウンロードするコマンド

f:id:twx:20190427132449p:plain
サイズの大きなファイルのダウンロードには確認画面がある

機械学習モデルや、動画ファイルなどサイズの大きなファイルを、他人のGoogle Driveからダウンロードしようとしたとき、上のような確認画面に遷移します。ダウンロードボタンをクリックすれば普通にダウンロードできるのですが、Linuxサーバやjupyter notebookなどのCUI環境でダウンロードしたいときは「ボタンをクリックする」ことができないので困ります。

ダウンロードボタンを右クリックして「リンクのアドレスをコピー」をしても、そのアドレスでは残念ながらwgetコマンドなどでダウンロードできません。

f:id:twx:20190427132824p:plain
右クリックして、アドレスをコピー
f:id:twx:20190427133117p:plain
wgetコマンドを試してみるが失敗…

以下のようなエラーが出てダウンロードできません。

--2019-04-27 04:20:32--  https://drive.google.com/uc?export=download
Resolving drive.google.com (drive.google.com)... 108.177.96.138, 108.177.96.102, 108.177.96.101, ...
Connecting to drive.google.com (drive.google.com)|108.177.96.138|:443... connected.
HTTP request sent, awaiting response... 400 Bad Request
2019-04-27 04:20:38 ERROR 400: Bad Request.

よく見ると、コピーされたアドレスにはconfirm=xxxxというパラメータが付与されています。この4桁の値が毎回変わるので、HTTPリクエストのセッションが変わると弾かれるみたいですね。

pythonでゴリ押す

この問題について、こちらで解決策が提示されていました。

Download-Large-File-From-Google-Drive-Using-Python/Download-Large-File-from-Google-Drive.ipynb at master · nsadawi/Download-Large-File-From-Google-Drive-Using-Python · GitHub

以下の関数download_file_from_google_driveを使えば、コマンドでダウンロードできるようになります。

import requests

def download_file_from_google_drive(id, destination):
    URL = "https://docs.google.com/uc?export=download"

    session = requests.Session()

    response = session.get(URL, params = { 'id' : id }, stream = True)
    token = get_confirm_token(response)

    if token:
        params = { 'id' : id, 'confirm' : token }
        response = session.get(URL, params = params, stream = True)

    save_response_content(response, destination)    

def get_confirm_token(response):
    for key, value in response.cookies.items():
        if key.startswith('download_warning'):
            return value

    return None

def save_response_content(response, destination):
    CHUNK_SIZE = 32768

    with open(destination, "wb") as f:
        for chunk in response.iter_content(CHUNK_SIZE):
            if chunk: # filter out keep-alive new chunks
                f.write(chunk)
file_id = '0B1fGSuBXAh1IeEpzajRISkNHckU'
destination = '/home/myusername/work/myfile.ext'
download_file_from_google_drive(file_id, destination)

試しにやってみた

Google Colaboratory (Googleが提供しているjupyter notebook風のアプリケーション)で、この関数を動かしてみました。

f:id:twx:20190427134037p:plain
ダウンロード成功!!

500MBのファイルがダウンロードできていることがわかります。成功です。

以上、本日はコマンドでGoogle Driveから大きなファイルをダウンロードする方法をご紹介しました。良い記事だと思っていただいた方は、SNSでのシェア、ブログからのリンク、「読者になる」ボタンのクリック、「★」ボタンのクリック、よろしくお願いします! ではまた次の記事でお会いしましょう!

Koma Hirokazu 's Hacklog ―― Copyright © 2018 Koma Hirokazu