Google Drive에 저장된 파일을 다운로드하는 Python 스크립트

4532 단어 GoogleDrivePython
배경:
최근에는 FTP를 이용한 파일 전송보다 Google Drive(Gsuite)를 이용해 파일을 교환하려는 사람들이 많다.
며칠 전 Google Drive를 통해 많은 이미지 파일을 받았고 이를 가공해 본사 서버에 업로드하는 작업을 진행할 때 Google Drive에 있는 파일을 다운로드하는 Python 스크립트를 준비했습니다.
①: 서비스 계정 준비
GCP에서 구글 드라이브에 사용되는 서비스 계정 키를 만듭니다.
서비스 계정의 생성은 아래 글에서 상세하게 설명되어 있습니다.
4.3단계에서 만든 서비스 계정에 있습니다.전자 우편 주소로 얻을 수 있습니다.이것은 아래 설정②에 사용됩니다.
기밀 키 JSON은 4.8단계에서 가져올 수 있으므로 다운로드하여 저장합니다.
②: 서비스 계정을 GoogleDrive의 공유 설정에 등록
GoogleDrive의 폴더 이름을 클릭하면 공유 링크가 표시되고 를 클릭합니다.

공유된 이용자 일람표에 ①설정을 통해 만든 서비스 계정을 등록한다.
이렇게 하면 이 서비스 계정을 통해 Google 드라이브 파일을 참조할 수 있습니다.

스크립트 구현
①에서 만든 JSON 파일을 파이톤에서 참조할 수 있는 곳에 저장합니다.
이번에는'lib/credentials/Google-drive-credentials'입니다.json '에 저장되었습니다.
이 글에 투고하는 것을 간소화했지만 다음 스크립트를 실행하면 파일을 통일적으로 다운로드할 수 있다.
import os

from django.conf import settings
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from httplib2 import Http
from oauth2client.service_account import ServiceAccountCredentials

SCOPES = ['https://www.googleapis.com/auth/drive']


def main() -> None:
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        credentials_file_path(), SCOPES
    )
    http_auth = credentials.authorize(Http())
    service = build('drive', 'v3', http=http_auth)
    parent = '1xDiN68Ocz1aXaABCDEFGHIJK'  # 先程共有したフォルダのIDでブラウザのURLから取得する
    while True:
        response = service.files().list(
            q=f"'{parent}' in parents" if parent else None,
            pageSize=100).execute()
        items = response.get('files', [])

        if not items:  # itemsが存在しない場合中断
            print(f'No files. {parent}')
            break

        for item in items:
            request = service.files().get_media(fileId=item.get('id'))
            file_path = f"to/save/path/{item.get('name')}"
            with open(file_path, 'wb', buffering=0) as fh:
                downloader = MediaIoBaseDownload(fh, request)
                done = False
                while done is False:
                    status, done = downloader.next_chunk()
                    print(f'Downloading... {file_path}, {status.total_size / 1024 / 1024}MB')


def credentials_file_path() -> str:
    """秘密鍵を保存しているファイルパス"""
    path = os.path.join(
        settings.BASE_DIR,
        'lib',
        'credentials',
        'google-drive-credentials.json'  # 設定①で取得したJSONファイルを格納した場所
    )
    return path

main()
① 폴더 내 파일이 100개 이상일 경우 nextPageToken 사용 개선
response.get('nextPageToken')에서 2페이지, 3페이지..., 이하 100건을 받을 수 있다.
page_token = None  # Noneの場合はページャーで初期値
while True:
    response = service.files().list(
        q=f"'{parent}' in parents" if parent else None,
        pageToken=page_token,
        pageSize=100).execute()
    items = response.get('files', [])
    page_token = response.get('nextPageToken')  # 対象件数が100件以上あれば、このpage_tokenを用いて次のページを取得する
    if not items:  # itemsが存在しない場合中断
        print(f'No files. {parent}')
        break
② 개선 ② TeamDrive 기능을 사용하는 조직과 파일을 공유할 수 없습니다.
TeamDrive에서 GoogleDrive 권한을 제어할 때 파일 목록을 가져올 때includeItems From AllDrives = True를 지정해야 합니다.그렇지 않으면 파일 목록을 가져올 수 없습니다.
response = self.service.files().list(
    q=f"'{parent}' in parents" if parent else None,
    includeItemsFromAllDrives=True, # TeamDriveも含めて参照することができる
    pageToken=page_token,
    pageSize=100).execute()
이 매개 변수도 최근에 바뀌었으니 공식 문서를 참고하시기 바랍니다.
③ 개선: 공유 폴더에 더 많은 폴더가 있으면 다시 가져옵니다.
def walk(parent:str = None):
  ....
  items = response.get('files', [])
  ....
  for item in items
      if item.get('mimeType') == 'application/vnd.google-apps.folder': # itemがフォルダであることを判定
          # 再帰的に取得する
          return walk(item.get('id'))
      else:
          ....# ファイルをダウンロードする
요약:
· Google Drive에서 파일을 통일적으로 다운로드할 수 있는 설정과 Python 스크립트를 소개합니다.
·Google Drive 인증은 이번에 서비스 계정을 사용해 보았습니다.예전에 OAuth에서 해봤는데 서비스 계정이 쉽게 참조할 수 있는 범위를 좁혀서 좋아요.😁
메리 크리스마스!

좋은 웹페이지 즐겨찾기