Skip to content

Instantly share code, notes, and snippets.

@grimpy
Forked from joshtch/gdrive-dl.py
Last active June 6, 2020 07:29
Show Gist options
  • Save grimpy/7dd579059d7c4c42d0528e4676edffaf to your computer and use it in GitHub Desktop.
Save grimpy/7dd579059d7c4c42d0528e4676edffaf to your computer and use it in GitHub Desktop.
Google Drive file downloader for Python, with progress bar with tqdm. Based on this SO answer https://stackoverflow.com/a/39225039/3175094
#!/usr/bin/env python
import requests
import sys
import os
from tqdm import tqdm
def download_file_from_google_drive(id, destination=None):
URL = "https://docs.google.com/uc?export=download"
session = requests.Session()
viewresp = session.get(URL, params={"id": id}, stream=True)
token = None
for key, value in viewresp.cookies.items():
if key.startswith("download_warning"):
token = value
break
else:
print("Could not find token for url")
#sys.exit(1)
params = {"id": id, "confirm": token}
response = session.get(URL, params=params, stream=True, headers={'Range': 'bytes=0-'})
CHUNK_SIZE = 32 * 1024
total_size = int(response.headers.get("content-length", 0))
if total_size == 0:
# attempt to get it out of Content-Range
range = response.headers.get('Content-Range', None)
if range:
total_size = int(range.split('/')[-1])
if destination is None or os.path.isdir(destination):
for segment in response.headers.get('Content-Disposition').split(';'):
if segment.startswith('filename='):
filename = segment.split('=', 1)[-1].strip('"')
break
else:
print("Could not find destination file")
sys.exit(1)
if destination is not None:
destination = os.path.join(destination, filename)
else:
destination = filename
partfile = destination + ".part"
stat = None
initial = 0
if os.path.exists(partfile):
stat = os.stat(partfile)
response.close()
response = session.get(URL, params=params, stream=True, headers={'Range': 'bytes={}-'.format(stat.st_size)})
initial = stat.st_size
range = response.headers.get('Content-Range', None)
with tqdm(desc=destination, total=total_size, initial=initial, unit="B", unit_scale=True) as pbar:
with open(partfile, "ab") as f:
f.seek(initial)
for chunk in response.iter_content(CHUNK_SIZE):
if chunk:
pbar.update(CHUNK_SIZE)
f.write(chunk)
os.rename(partfile, destination)
if __name__ == "__main__":
import argparse
from urllib import parse
parser = argparse.ArgumentParser()
parser.add_argument("-url", dest="url", required=True)
parser.add_argument("-dest", dest="dest")
options = parser.parse_args()
# TAKE ID FROM SHAREABLE LINK
if options.url.startswith("https://"):
parsedurl = parse.urlparse(options.url)
query = parse.parse_qs(parsedurl.query)
if "id" not in query:
print("Link does not contain fileid")
sys.exit(1)
file_id = query["id"][0]
else:
file_id = options.url
destination = options.dest
download_file_from_google_drive(file_id, destination)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment