メインコンテンツまでスキップ

GoogleDrive のファイル操作(アップロード/ダウンロード)を自動化する

Pythonを使って「GoogleDriveへファイルアップロード」「GoogleDriveからのファイルダウンロード」を実現する手順を解説します。

概要

  • GoogleDriveへ自動アクセスするためGoogle Cloud projectを登録します。
  • GoogleDriveへログインし、認証コードを取得します。
  • 認証コードからアクセストークンを取得します。
  • アクセストークンを利用してGoogle Drive APIにより「GoogleDriveへのファイルアップロード」「GoogleDriveからのファイルダウンロード」を実現します。

GoogleDriveへ自動アクセスするためGoogle Cloud projectを登録

OAuthの設定

image image image

  • 承認済みのリダイレクト URIにhttp://localhost:4200/を設定します。
    image

  • クライアントIDクライアントシークレット を取得します。
    image

GoogleDriveへログインし、認証コードを取得

トークン取得用URLを作成し、ブラウザへ貼り付けます。

  • 下記のclient_id=xxxxxxxxxxxxxxxxxxxxxxxxには上記で取得したクライアントIDを指定します。
https://accounts.google.com/o/oauth2/v2/auth?scope=https%3A//www.googleapis.com/auth/drive&access_type=offline&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2F&client_id=xxxxxxxxxxxxxxxxxxxxxxxx
  • サインインが完了すると認証コードが発行されるので取得します。
    image image image

  • code=xxxxxxxxxxxxxと表示されます。このxxxxxxxxxxxxxが認証コードです。
    image 注意
    URLに表示される認証コードはURLエンコードされています。
    認証コードはデコードしてから利用する必要があります。
    例 4%2F0Ad・・・ => 4/0Ad・・・
    参考サイト

認証コードからアクセストークンを取得

  • 下記手順を参考に認証コードからアクセストークンを取得します。
    更新トークンとアクセス トークンの認証コードを交換する

  • aaaaaaaaaaaaaaaaaには上記で取得した認証コードを指定します。

  • bbbbbbbbbbbbbbbbbには上記で取得したクライアントIDを指定します。

  • cccccccccccccccccには上記で取得したクライアントシークレットを指定します。

import urllib.parse
import urllib.request
import json

def get_googledrive_token(code: str):

apl_client_id= "bbbbbbbbbbbbbbbbbbbbbbbbb"
client_secret = "cccccccccccccccccccccccc"
redirect_url = "http://localhost:4200/"

url = "https://oauth2.googleapis.com/token"
method = "POST"
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}

params = {
"client_id": apl_client_id
,"redirect_uri": redirect_url
,"client_secret": client_secret
,"code": code
,"grant_type": "authorization_code"
}

encoded_param = urllib.parse.urlencode(params).encode()

request = urllib.request.Request(url, data=encoded_param, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()
dat = json.loads(body)
print(dat)

if __name__ == '__main__':

code = "aaaaaaaaaaaaaaaaaaaaaaaa"
get_googledrive_token(code)
  • 下記のようなjsonが取得できます。
  • この中に以降の処理で必要なアクセストークン(access_token)及びリフレッシュトークン(refresh_token)が含まれます。
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

アクセストークンの更新

  • 下記手順を参考にリフレッシュトークンからアクセストークンを取得します。
    アクセス トークンの更新(オフライン アクセス)

  • aaaaaaaaaaaaaaaaaには上記で取得したリフレッシュトークンを指定します。

  • bbbbbbbbbbbbbbbbbには上記で取得したクライアントIDを指定します。

  • cccccccccccccccccには上記で取得したクライアントシークレットを指定します。

import urllib.parse
import urllib.request
import json

def get_googledrive_reflesh_token(refresh_token: str):

apl_client_id= "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
client_secret = "cccccccccccccccccccccccccccccccccc"
redirect_url = "http://localhost:4200/"

url = "https://oauth2.googleapis.com/token"
method = "POST"
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}

params = {
"client_id": apl_client_id
,"redirect_uri": redirect_url
,"client_secret": client_secret
,"refresh_token": refresh_token
,"grant_type": "refresh_token"
}

encoded_param = urllib.parse.urlencode(params).encode()

request = urllib.request.Request(url, data=encoded_param, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()
dat = json.loads(body)
print(dat)
print("access_token:" + dat["access_token"])

if __name__ == '__main__':

refresh_token = "aaaaaaaaaaaaaaaaaaaaaa"
get_googledrive_reflesh_token(refresh_token)

  • 下記のようなjsonが取得できます。
  • この中に以降の処理で必要なアクセストークン(access_token)が含まれます。
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
"token_type": "Bearer"
}

アクセストークンの利用

GoogleDriveのフォルダ内容一覧取得

import urllib.parse
import urllib.request
import json

def get_googledrive_item(access_token: str, id: str):

url = "https://www.googleapis.com/drive/v3/files/" + id
method = "GET"
headers = {
'Authorization': 'Bearer ' + access_token
}

request = urllib.request.Request(url, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()
print(body)

def get_googledrive_list(access_token: str):

url = "https://www.googleapis.com/drive/v2/files/root/children"
method = "GET"
headers = {
'Authorization': 'Bearer ' + access_token
}

request = urllib.request.Request(url, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()
#print(body)
dat = json.loads(body)
print(dat)
if dat["items"]:
list = dat["items"]
for item in list:
print(item["id"])
get_googledrive_item(access_token,item["id"])
print(" ")

if __name__ == '__main__':

access_token = "aaaaaaaaaaaaaaaaaaa"
get_googledrive_list(access_token)
  • 下記のようなjsonが取得できます。
{'kind': 'drive#file', 'id': 'xxxxxxxxxxxxx', 'name': 'pictures', 'mimeType': 'application/vnd.google-apps.folder'}

GoogleDriveへのファイル登録

  • 下記手順を参考にGoogleDriveへファイルを登録します。
    Perform a resumable upload

  • aaaaaaaaaaaaaaaaaには上記で取得したアクセストークンを指定します。

  • bbbbbbbbbbbbbbbbbには上記で取得した格納対象フォルダのidを指定します。

import pathlib
import urllib.parse
import urllib.request
import json
import os

def upload_file_session(access_token: str, upload_url:str, target_file:pathlib.Path):

contentLength = os.path.getsize(target_file)
print("contentLength:" + str(contentLength))

with open(target_file, 'rb') as f:

file_split_size = 1024 * 1024 * 10

current_pos = 0

while current_pos < contentLength:

remain = contentLength - current_pos
next_size = file_split_size
if remain <= file_split_size:
next_size = remain

file_body = f.read(next_size)

reange_string = "bytes " + str(current_pos) + "-" + str(current_pos + next_size -1) + "/" + str(contentLength)
print(reange_string)

method = "PUT"
headers = {
'Content-Type': 'application/octet-stream'
,'Authorization': "Bearer " + access_token
,'Content-Length': next_size
,'Content-Range': reange_string
}

request = urllib.request.Request(upload_url, data=file_body, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()
print(body)
except urllib.error.HTTPError as err:
print(err)

current_pos = current_pos + next_size



def upload_file(access_token: str, parent_id: str, target_file:pathlib.Path):

url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable"
method = "POST"
headers = {
'Content-Type': 'application/json'
,'Authorization': 'Bearer ' + access_token
}

params = {
"name": target_file.name,
"parents": [parent_id]
}

encoded_param = json.dumps(params).encode("utf-8")
print(encoded_param)
request = urllib.request.Request(url, data=encoded_param, method=method, headers=headers)

with urllib.request.urlopen(request) as res:
headers = res.info()
print(headers)
upload_url = headers["Location"]
print("upload_url:" + upload_url)
upload_file_session(access_token,upload_url,target_file)

if __name__ == '__main__':

access_token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
parent_id = "bbbbbbbbbbbbbbbbbbbbbbbbb"
target_file = pathlib.Path("c:/tmp/テスト.docx")

upload_file(access_token,parent_id,target_file)

GoogleDriveからのファイルダウンロード

  • 下記手順を参考にGoogleDriveからファイルをダウンロードします。
    https://developers.google.com/drive/api/v3/reference/files/get

  • aaaaaaaaaaaaaaaaaには上記で取得したアクセストークンを指定します。

  • bbbbbbbbbbbbbbbbbには上記で取得したダウンロード対象ファイルのidを指定します。

import urllib.parse
import urllib.request
import urllib
import json

def download_file_content(access_token: str, item_id:str, file_name:str):

url = "https://www.googleapis.com/drive/v3/files/" + urllib.parse.quote(item_id)

method = "GET"
headers = {
'Authorization': 'Bearer ' + access_token
}

params = {
"alt":"media"
}

param_str = urllib.parse.urlencode(params)
print(param_str)
url = url + "?" + param_str

request = urllib.request.Request(url, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()
save_name = "c:/tmp/" + file_name
with open(save_name, mode="wb") as f:
f.write(body)


def download_file(access_token: str, item_id:str):

url = "https://www.googleapis.com/drive/v3/files/" + urllib.parse.quote(item_id)

method = "GET"
headers = {
'Authorization': 'Bearer ' + access_token
}

params = {
"fields": "id,name,webContentLink",
}

param_str = urllib.parse.urlencode(params)
print(param_str)
url = url + "?" + param_str

request = urllib.request.Request(url, method=method, headers=headers)
with urllib.request.urlopen(request) as res:
body = res.read()

dat = json.loads(body)
print(dat)

file_name = dat["name"]

print("file_name:"+ file_name)

download_file_content(access_token,item_id,file_name)

if __name__ == '__main__':

access_token = "aaaaaaaaaaaaaaaaaaaaaaa"
item_id = "bbbbbbbbbbbbbbbbbbbbbbbbbbbb"

download_file(access_token,item_id)

👇関連記事

👇参考URL

[keywords]
GoogleDrive TypeScript Python

GoogleDrive のファイル操作(アップロード/ダウンロード)を自動化する

更新日:2024年02月07日

ITとソフトウェアの人気オンラインコースHP Directplus -HP公式オンラインストア-