如何从包含超过 50 个文件的 Google 云端硬盘文件夹中下载所有文件?

Gen*_*_ID 7 python google-drive-api

我不知道如何编写一个程序来从可公开访问的 Google Drive 文件夹中下载所有文件,该文件夹中有 1,000 多个文件。

这是我到目前为止所尝试过的:

import gdown
url = 'https://drive.google.com/drive/folders/MY-PUBLICLY-ACCESSIBLE-FOLDER-ID?usp=drive_link'
gdown.download_folder(url, quiet=True, remaining_ok=True, use_cookies=False)
Run Code Online (Sandbox Code Playgroud)

但它只下载了 50 个文件。

Oln*_*ey1 7

您可以使用 Google Drive API:

https://developers.google.com/drive/api/quickstart/python

这是我过去使用过的脚本:

from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from google_auth_oauthlib.flow import InstalledAppFlow
import io
import os

# Define the scopes
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']

# Obtain your Google credentials
def get_credentials():
    flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
    creds = flow.run_local_server(port=0)
    return creds

# Build the downloader
creds = get_credentials()
drive_downloader = build('drive', 'v3', credentials=creds)

# Replace 'FOLDER_ID' with your actual Google Drive folder ID
folder_id = 'FOLDER_ID'
query = f"Folder ID '{folder_id}'"
results = drive_downloader.files().list(q=query, pageSize=1000).execute()
items = results.get('files', [])

# Download the files
for item in items:
    request = drive_downloader.files().get_media(fileId=item['id'])
    f = io.FileIO(item['name'], 'wb')
    downloader = MediaIoBaseDownload(f, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
        print(f"Download {int(status.progress() * 100)}.")

print(f"Downloaded {len(items)} files from the folder.")
Run Code Online (Sandbox Code Playgroud)


Ori*_*PhD 1

解决方法:

由于gdowndownload_folder函数不关心需要下载多少个 50 个或更少文件的子temp_folder文件夹,我们可以使用以下函数通过创建所有文件所在的位置来组织要保存在新路径中的文件夹中的文件移动到包含 50 个或更少文件的子文件夹中,然后运行gdown​​sdownload_folder函数:

import os

def organize_folder_into_subfolders(path_to_original_folder, max_number_of_files_per_subfolder=50):
    '''Moves all files in a folder into newly created subfolders comprising of the max_number_of_files_per_subfolder or fewer'''
    files_in_folder = os.listdir(path_to_original_folder)
    if not path_to_original_folder.endswith('/'):
        path_to_original_folder += '/'
    temp_path_to_original_folder = path_to_original_folder + 'temp_folder'
    os.makedirs(temp_path_to_original_folder)
    subfolders_dict = {'temp_subfolder_0': []}
    os.makedirs(temp_path_to_original_folder + '/' + 'temp_subfolder_0')
    for _file_name in files_in_folder:
        if len(subfolders_dict['temp_subfolder_' + str(len(subfolders_dict) - 1)]) == max_number_of_files_per_subfolder:
            subfolders_dict['temp_subfolder_' + str(len(subfolders_dict))] = []
            os.makedirs(temp_path_to_original_folder + '/' + 'temp_subfolder_' + str(len(subfolders_dict) - 1))
        subfolders_dict['temp_subfolder_' + str(len(subfolders_dict) - 1)].append(_file_name)
    for _file_subfolder_path, _file_names in subfolders_dict.items():
        for _file_name in _file_names:
            os.rename(path_to_original_folder + _file_name, temp_path_to_original_folder + '/' + _file_subfolder_path + '/' + _file_name)
    return subfolders_dict
Run Code Online (Sandbox Code Playgroud)

然后运行该download_folder函数:

import gdown
url = 'https://drive.google.com/drive/folders/1OXV4qhFF_qJ8VqyrXpR7CzHDsToaqY_W?usp=drive_link'
gdown.download_folder(url, quiet=True, use_cookies=False, remaining_ok=True)
Run Code Online (Sandbox Code Playgroud)

然后,如果您希望原始文件夹和新文件夹不组织为子文件夹,我们可以使用此功能“撤消”或将文件放回到原始文件夹和新文件夹中,并删除临时子文件夹:

import os

def undo_organize_folder_into_subfolders(path_to_original_folder, path_to_new_folder, subfolders_dict):
    '''Moves the files organized as subfolders back to the original & new folders and deletes subfolders'''
    if not path_to_original_folder.endswith('/'):
        path_to_original_folder += '/'
    if not path_to_new_folder.endswith('/'):
        path_to_new_folder += '/'
    temp_path_to_original_folder = path_to_original_folder + 'temp_folder'
    temp_path_to_new_folder = path_to_new_folder + 'temp_folder'
    for _file_subfolder_path, _file_names in subfolders_dict.items():
        for _file_name in _file_names:
            os.rename(temp_path_to_original_folder + '/' + _file_subfolder_path + '/' + _file_name, path_to_original_folder + _file_name)
            os.rename(temp_path_to_new_folder + '/' + _file_subfolder_path + '/' + _file_name, path_to_new_folder + _file_name)
        os.rmdir(temp_path_to_original_folder + '/' + _file_subfolder_path)
        os.rmdir(temp_path_to_new_folder + '/' + _file_subfolder_path)
    os.rmdir(temp_path_to_original_folder)
    os.rmdir(temp_path_to_new_folder)
Run Code Online (Sandbox Code Playgroud)

只需确保您设置了当前的工作目录即可:

from google.colab import drive
drive.mount('/content/drive', force_remount=True)
%cd '/content/drive/My Drive/Colab Notebooks/'
Run Code Online (Sandbox Code Playgroud)