You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:07:03