본 포스트에서는 구글 드라이브 (Google Drive) 에 있는 파일을 Python 코드를 통해 다운로드하는 방법을 소개합니다. 예제 코드도 함께 제공됩니다.
gdown 을 활용한 구글 드라이브 파일 원격 다운로드
파일을 원격에서 접근하기 위한 다음과 같은 사전 작업이 필요합니다.
gdown
설치
자세한 내용은 링크를 참조바랍니다.
pip install gdown
# to upgrade
pip install --upgrade gdown
- 파일 권한 변경
파일 우클릭 --> Get Link --> Restricted 에서 Anyone with the link 로 파일 권한 변경
다음과 같은 권한 설정이 된 파일만이 gdown
을 통해 접근이 가능합니다.
사전 작업이 모두 완료되었다면, 파일 우클릭을 통해 파일의 공유 link를 가져옵니다. 예를 들어, 아래와 같은 공유 링크가 있다고 가정하겠습니다.
# example of the share link
https://drive.google.com/file/d/1PAuhzIGWh_FRHLM8jj-utTZRVY5q5v/view?usp=share_link
google drive는 https://drive.google.com/file/d 라는 prefix 와 파일을 식별할 수 있는 1PAuhzIGWh_FRHLM8jj-utTZRVY5q5v
라는 unique id 가 할당되고 링크의 종류에 따라 /view?usp=share_link 또는 edit?usp=share_link 등과 같은 suffix가 붙기도합니다.
gdown
을 통해 파일을 식별하기 위해서는 해당 파일을 식별할 수 있는 unique id 를 적절히 넘겨주어야 합니다. gdown
은 download라는 함수를 이용해 url과 output filename을 인자로 받아 특정 url에 접근하여 지정된 path에 output을 저장합니다. 구글 드라이브에서 직접 copy해온 링크를 그대로 붙여넣을 경우 download는 동작하지만 정상적인 파일이 다운로드되지 않을 것입니다.
# gdown.download(downloadable_url, output_filename)
link = "https://drive.google.com/file/d/1PAuhzIGWh_FRHLM8jj-utTZRVY5q5v/view?usp=share_link"
output_filename = "example"
gdown.download(link, output_filename) # doesn't work
이는 gdown
이 인식할 수 있는 downlodable url 은 아래와 같은 포맷을 따라야합니다. https://drive.google.com/uc?id=
라는 suffix뒤에 1PAuhzIGWh_FRHLM8jj-utTZRVY5q5v
라는 unique_file_id 가 붙습니다.
def make_download_url(file_id):
"""Make downlodable URL from gdrive"""
return "https://drive.google.com/uc?id=" + file_id
즉, 요약하자면
- 구글 드라이브에서 파일의 권한을 Anyone with the link로 변경 후 공유 링크를 가져온다
- unique id 를 추출한다.
- URL 포맷 변환 후 gdown.download를 활용해 원격 파일 다운로드를 한다.
위 3가지 프로세스를 파이썬 스크립트로 만든것은 아래와 같습니다.
import re
import gdown
from urllib.parse import urlparse
def get_gdrive_file_id(url):
"""Extracting file id from shared link of google drive"""
parts = urlparse(url)
if re.match(r"(drive|docs)[.]google[.]com", parts.netloc) is None:
return None
match = re.match(r"/file/d/(?P<id>[^/]*)", parts.path)
if match is None:
return None
return match.group("id")
def make_download_url(file_id):
"""Make downlodable URL from gdrive"""
return "https://drive.google.com/uc?id=" + file_id
gdrive_file_link = 'https://drive.google.com/file/d/1PAuhzIGWh_FRHLM8jj-utTZRVY5q5v/view?usp=share_link'
unique_file_id = get_gdrive_file_id(gdrive_file_link) # Extracting unique file id from the link
downlodable_url = make_download_url(unique_file_id)
gdown.download(downlodable_url, "output") # Downloading the file through python
가끔 대용량 파일을 다운로드하거나 불안정한 네트워크로 인해 정상적으로 파일이 다운로드가 완료된 것인지 확인하기 힘든 경우가 있습니다. 이럴 경우 원본 파일의 md5sum hash값을 이용해 다운로드가 적절하게 된 것인지 확인하는 아래와 같은 로직을 추가할 수 있습니다. 적절하게 다운로드가 되었는지 체크 하기 위해 원본 파일의 md5sum 값이 필요합니다.
import hashlib
import sys
def compute_md5(file, chunk_size=1024 * 1024):
"""Computing md5sum value"""
mdf5sum = hashlib.md5(**dict(usedforsecurity=False) if sys.version_info >= (3, 9) else dict())
with open(file, "rb") as f:
for chunk in iter(lambda: f.read(chunk_size), b""):
mdf5sum.update(chunk)
return mdf5sum.hexdigest()
def check_md5sum(file, md5sum):
"""Check whether downloaded file has correct md5sum value"""
return md5sum == compute_md5(file)
output_file = "output"
md5sum_value = compute_md5(output_file)
ground_truth_md5sum = '32cd9b4e6355fb05a1a6b66352119e47'
check_md5sum(md5sum_value, ground_truth_md5sum) # True or False
MD5SUM 체크 로직까지 추가한 전체 스크립트는 아래를 참조하시기 바랍니다.
import re
import sys
import gdown
import hashlib
from urllib.parse import urlparse
def get_gdrive_file_id(url):
"""Extracting file id from shared link of google drive"""
parts = urlparse(url)
if re.match(r"(drive|docs)[.]google[.]com", parts.netloc) is None:
return None
match = re.match(r"/file/d/(?P<id>[^/]*)", parts.path)
if match is None:
return None
return match.group("id")
def make_download_url(file_id):
"""Make downlodable URL from gdrive"""
return "https://drive.google.com/uc?id=" + file_id
def compute_md5(file, chunk_size=1024 * 1024):
"""Computing md5sum value"""
mdf5sum = hashlib.md5(**dict(usedforsecurity=False) if sys.version_info >= (3, 9) else dict())
with open(file, "rb") as f:
for chunk in iter(lambda: f.read(chunk_size), b""):
mdf5sum.update(chunk)
return mdf5sum.hexdigest()
def check_md5sum(file, md5sum):
"""Check whether downloaded file has correct md5sum value"""
return md5sum == compute_md5(file)
if __name__ == "__main__":
# Processing inputs of gdown.download
gdrive_file_link = 'https://drive.google.com/file/d/1PAuhzIGWh_FRHLM8jj-utTZRVY5q5v/view?usp=share_link'
unique_file_id = get_gdrive_file_id(gdrive_file_link) # Extracting unique file id from the link
downlodable_url = make_download_url(unique_file_id)
output_file = "output"
# download the file
gdown.download(downlodable_url, output_file) # Downloading the file through python
# check whether the file has downloaded well
md5sum_value = compute_md5(output_file)
ground_truth_md5sum = '32cd9b4e6355fb05a1a6b66352119e47'
if check_md5sum(md5sum_value, ground_truth_md5sum) # True or False
print("Download has been completed")
else:
print("Download has been failed")
이상으로 Python 을 활용한 구글 드라이브 파일 원격 다운로드 하는 방법을 소개했습니다.
도움이 되셨다면, 공감 버튼 부탁드립니다 :)

'리눅스 > Ubuntu16.04' 카테고리의 다른 글
[CUDA ERROR] nvidia-smi has failed because it couldn't communicate with the nvidia driver (0) | 2021.07.10 |
---|---|
[Ubuntu] 구글드라이브(Google Drive) 대용량 파일 원격 다운로드 (2) | 2021.07.05 |