Google Drive API统计非谷歌类型文件时返回文件夹大小为0
问题排查与修复方案
1. 服务账号无文件夹访问权限
服务账号是独立身份,需将目标共享文件夹共享给服务账号邮箱(在drivedownload-credentials.json文件的client_email字段中获取),否则服务账号无法读取文件夹内容,导致返回大小为0。
2. 未递归遍历子文件夹
原代码仅读取目标文件夹的直接子文件,未处理嵌套子文件夹,需修改计算函数实现递归遍历。
3. 未过滤谷歌原生文件
谷歌原生文件(如Sheets、Docs等)无size属性且不计入存储空间,需通过MIME类型(开头为application/vnd.google-apps.)排除这类文件。
修复后的完整代码
import os from googleapiclient.discovery import build from google.oauth2.service_account import Credentials as ServiceAccountCredentials # 替换为你的凭证文件路径 JSON_CREDS_PATH = 'drivedownload-credentials.json' # 共享文件夹ID SHARED_FOLDER_ID = 'XXX-XXXXXXXXXXXXXXXXXXXXXXx' def get_drive_service(): credentials = None if os.path.exists(JSON_CREDS_PATH): credentials = ServiceAccountCredentials.from_service_account_file( JSON_CREDS_PATH, scopes=['https://www.googleapis.com/auth/drive'] ) else: print("Credentials JSON file not found.") if credentials: return build('drive', 'v3', credentials=credentials) def calculate_folder_size(service, folder_id): total_size = 0 page_token = None while True: # 查询条件:排除谷歌原生文件,获取文件/文件夹的ID、大小、类型 response = service.files().list( q=f"'{folder_id}' in parents and not mimeType contains 'application/vnd.google-apps.'", spaces='drive', fields='files(id, size, mimeType), nextPageToken', pageToken=page_token ).execute() items = response.get('files', []) for item in items: # 递归处理子文件夹 if item['mimeType'] == 'application/vnd.google-apps.folder': total_size += calculate_folder_size(service, item['id']) else: # 仅统计有size属性的非谷歌文件 if 'size' in item: total_size += int(item['size']) page_token = response.get('nextPageToken', None) if not page_token: break return total_size def main(): drive_service = get_drive_service() if drive_service: folder_size = calculate_folder_size(drive_service, SHARED_FOLDER_ID) # 格式化大小为易读单位 def format_size(size_bytes): units = ['B', 'KB', 'MB', 'GB', 'TB'] size = size_bytes unit_idx = 0 while size >= 1024 and unit_idx < len(units)-1: size /= 1024 unit_idx += 1 return f"{size:.2f} {units[unit_idx]}" print(f"共享文件夹内非谷歌文件总大小: {format_size(folder_size)}") if __name__ == "__main__": main()
关键修复点
- 递归遍历子文件夹:识别文件夹类型项目,递归调用计算函数统计嵌套内容。
- 过滤谷歌原生文件:通过查询条件排除MIME类型为谷歌应用的文件。
- 安全读取size属性:增加判断避免特殊非谷歌文件因缺少size字段报错。
- 大小单位格式化:将字节转换为KB/MB/GB等易读单位(可选功能)。
内容的提问来源于stack exchange,提问作者IgorM
相关产品推荐
相关产品推荐

