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

Python脚本连接Google Drive遇credentials.json找不到错误求助

问题描述

我正尝试编写Python脚本实现以下功能:

  • 导入所需库
  • 连接并认证Google Drive
  • 检查Google Drive指定文件夹的文件名,将本地特定文件夹中未上传的文件上传至该文件夹
  • 每小时重复执行,无新文件则重启循环

我写了如下代码,但运行时提示找不到credentials.json文件,该文件和settings.yaml、Setup.py在同一目录下,原本期望运行时会跳转到登录页面。我Python基础很差,之前只用过Lua写《我的世界》模组,求帮忙解决。

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']


def main():
    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        service = build('drive', 'v3', credentials=creds)

        # Call the Drive v3 API
        results = service.files().list(
            pageSize=10, fields="nextPageToken, files(id, name)").execute()
        items = results.get('files', [])

        if not items:
            print('No files found.')
            return
        print('Files:')
        for item in items:
            print(u'{0} ({1})'.format(item['name'], item['id']))
    except HttpError as error:
        # TODO(developer) - Handle errors from drive API.
        print(f'An error occurred: {error}')


if __name__ == '__main__':
    main()
解决方案

1. 解决credentials.json找不到的问题

  • 强制脚本切换到自身目录:运行脚本时Python的工作目录可能不是文件所在路径,在脚本最开头添加这段代码,让脚本自动切换到自己的目录:
import os
# 获取脚本所在文件夹路径
script_dir = os.path.dirname(os.path.abspath(__file__))
# 切换到该目录
os.chdir(script_dir)
  • 核对文件名:确保文件名是credentials.json,别打错字,注意大小写(Mac/Linux系统区分大小写,Windows不区分),也别多了空格或隐藏后缀。

2. 调整权限以支持文件上传

原代码的权限是只读的,无法上传文件,需要修改SCOPES为上传权限:

SCOPES = ['https://www.googleapis.com/auth/drive.file']

这个权限仅允许脚本操作自己上传的文件,安全性更高。修改后删除之前生成的token.json,重新运行脚本就能跳转到登录页面完成认证。

3. 实现指定文件夹的文件检查与上传

原代码仅列出前10个文件,需要修改为只获取目标Drive文件夹下的文件:

  1. 先从Google Drive文件夹的URL中提取ID(比如https://drive.google.com/drive/folders/abc123中的abc123就是文件夹ID)
  2. 修改文件列表请求代码:
# 替换成你的目标文件夹ID
TARGET_FOLDER_ID = "你的文件夹ID"
# 仅获取该文件夹下的文件
results = service.files().list(
    q=f"'{TARGET_FOLDER_ID}' in parents",
    fields="nextPageToken, files(id, name)").execute()
  1. 添加函数对比本地与Drive文件,上传未存在的文件:
def upload_missing_files(service, local_folder_path, drive_folder_id):
    # 获取Drive文件夹内的所有文件名
    drive_files = service.files().list(
        q=f"'{drive_folder_id}' in parents",
        fields="files(name)").execute().get('files', [])
    drive_filenames = {file['name'] for file in drive_files}

    # 遍历本地文件夹文件
    for filename in os.listdir(local_folder_path):
        full_local_path = os.path.join(local_folder_path, filename)
        # 仅处理文件,跳过子文件夹
        if os.path.isfile(full_local_path) and filename not in drive_filenames:
            # 设置文件元数据(存储位置、文件名)
            file_metadata = {
                'name': filename,
                'parents': [drive_folder_id]
            }
            # 上传文件
            uploaded_file = service.files().create(
                body=file_metadata,
                media_body=full_local_path,
                fields='id'
            ).execute()
            print(f"已上传: {filename},文件ID: {uploaded_file.get('id')}")

记得在main()函数中调用这个函数,传入本地文件夹路径和Drive文件夹ID。

4. 实现每小时重复执行

用time.sleep()实现定时循环,调整主函数结构:

import time

def main():
    # 保留原有的认证逻辑
    # ...
    # 调用上传函数
    upload_missing_files(service, "/你的本地文件夹路径", TARGET_FOLDER_ID)

def main_loop():
    while True:
        main()
        print("等待1小时后再次检查...")
        # 3600秒等于1小时
        time.sleep(3600)

if __name__ == '__main__':
    main_loop()

内容的提问来源于stack exchange,提问作者Nicholas Clegg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:10:39