猿问

如何使用 Python 和 Drive API v3 将文件上传到 Google Drive

我尝试使用 Python 脚本从本地系统将文件上传到 Google Drive,但我不断收到 HttpError 403。脚本如下:


from googleapiclient.http import MediaFileUpload

from googleapiclient import discovery

import httplib2

import auth


SCOPES = "https://www.googleapis.com/auth/drive"

CLIENT_SECRET_FILE = "client_secret.json"

APPLICATION_NAME = "test"

authInst = auth.auth(SCOPES, CLIENT_SECRET_FILE, APPLICATION_NAME)

credentials = authInst.getCredentials()

http = credentials.authorize(httplib2.Http())

drive_serivce = discovery.build('drive', 'v3', credentials=credentials)

file_metadata = {'name': 'gb1.png'}

media = MediaFileUpload('./gb.png',

                        mimetype='image/png')

file = drive_serivce.files().create(body=file_metadata,

                                    media_body=media,

                                    fields='id').execute()

print('File ID: %s' % file.get('id'))

错误是:


googleapiclient.errors.HttpError: <HttpError 403 when requesting

https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&alt=json&fields=id 

returned "Insufficient Permission: Request had insufficient authentication scopes.">

我在代码中使用了正确的范围还是遗漏了什么?


我还尝试了我在网上找到的一个脚本,它工作正常,但问题是它需要一个静态令牌,该令牌会在一段时间后过期。那么如何动态刷新令牌呢?


这是我的代码:


import json

import requests

headers = {

    "Authorization": "Bearer TOKEN"}

para = {

    "name": "account.csv",

    "parents": ["FOLDER_ID"]

}

files = {

    'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),

    'file': ('mimeType', open("./test.csv", "rb"))

}

r = requests.post(

    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",

    headers=headers,

    files=files

)

print(r.text)


慕哥9229398
浏览 390回答 6
6回答

墨色风雨

要使用范围“https://www.googleapis.com/auth/drive”,您需要提交谷歌应用程序进行验证。查找范围的图像因此,使用范围“https://www.googleapis.com/auth/drive.file”而不是“https://www.googleapis.com/auth/drive”来上传文件而不进行验证。也使用 SCOPES 作为列表。前任:SCOPES = ['https://www.googleapis.com/auth/drive.file']我可以使用上面的 SCOPE 成功地将文件上传和下载到谷歌驱动器。

开满天机

“权限不足:请求的身份验证范围不足。”意味着您已通过身份验证的用户尚未授予您的应用程序执行您尝试执行的操作的权限。files.create方法要求您已使用以下范围之一对用户进行身份验证。而您的代码似乎确实使用了完整的驱动范围。我怀疑发生的事情是您已经对用户进行了身份验证,然后更改了代码中的范围,并且没有促使用户再次登录并同意。您需要从您的应用程序中删除用户的同意,方法是让他们直接在他们的谷歌帐户中删除它,或者只是删除您存储在应用程序中的凭据。这将强制用户再次登录。谷歌登录还有一个批准提示强制选项,但我不是 python 开发人员,所以我不完全确定如何强制。它应该类似于下面的 prompt='consent' 行。flow = OAuth2WebServerFlow(client_id=CLIENT_ID,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;client_secret=CLIENT_SECRET,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;scope='https://spreadsheets.google.com/feeds '+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'https://docs.google.com/feeds',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;redirect_uri='http://example.com/auth_return',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;prompt='consent')同意屏幕如果操作正确,用户应该会看到这样的屏幕提示他们授予您对其云端硬盘帐户的完全访问权限令牌泡菜如果您在https://developers.google.com/drive/api/v3/quickstart/python遵循谷歌教程,则需要删除包含用户存储同意的 token.pickle。if os.path.exists('token.pickle'):&nbsp; &nbsp; with open('token.pickle', 'rb') as token:&nbsp; &nbsp; &nbsp; &nbsp; creds = pickle.load(token)

小怪兽爱吃肉

您可以使用google-api-python-client构建Drive 服务以使用Drive API。按照此答案的前 10 个步骤获得您的授权。如果您希望用户只通过一次同意屏幕,则将凭据存储在文件中。它们包括一个刷新令牌,应用程序可以在 expired 之后使用它来请求授权。例子使用有效的Drive Service,您可以通过调用如下函数来上传文件upload_file:def upload_file(drive_service, filename, mimetype, upload_filename, resumable=True, chunksize=262144):&nbsp; &nbsp; media = MediaFileUpload(filename, mimetype=mimetype, resumable=resumable, chunksize=chunksize)&nbsp; &nbsp; # Add all the writable properties you want the file to have in the body!&nbsp; &nbsp; body = {"name": upload_filename}&nbsp;&nbsp; &nbsp; request = drive_service.files().create(body=body, media_body=media).execute()&nbsp; &nbsp; if getFileByteSize(filename) > chunksize:&nbsp; &nbsp; &nbsp; &nbsp; response = None&nbsp; &nbsp; &nbsp; &nbsp; while response is None:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chunk = request.next_chunk()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if chunk:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status, response = chunk&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if status:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Uploaded %d%%." % int(status.progress() * 100))&nbsp; &nbsp; print("Upload Complete!")现在传入参数并调用函数...# Upload fileupload_file(drive_service, 'my_local_image.png', 'image/png', 'my_imageination.png' )您将在 Google Drive 根文件夹中看到名为my_imageination.png的文件。有关 Drive API v3 服务和可用方法的更多信息,请点击此处。getFileSize()功能:def getFileByteSize(filename):&nbsp; &nbsp; # Get file size in python&nbsp; &nbsp; from os import stat&nbsp; &nbsp; file_stats = stat(filename)&nbsp; &nbsp; print('File Size in Bytes is {}'.format(file_stats.st_size))&nbsp; &nbsp; return file_stats.st_size上传到驱动器中的某些文件夹很容易...只需在请求正文中添加父文件夹 ID。这是File 的属性。例子:request_body = {&nbsp; "name": "getting_creative_now.png",&nbsp; "parents": ['myFiRsTPaRentFolderId',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'MyOtherParentId',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'IcanTgetEnoughParentsId'],}

九州编程

回答:删除您的token.pickle文件并重新运行您的应用程序。更多信息:只要您拥有正确的凭据集,那么在更新应用程序范围时所需要做的就是重新获取令牌。删除位于应用程序根文件夹中的令牌文件,然后再次运行应用程序。如果你有https://www.googleapis.com/auth/drive范围,并且在开发者控制台中启用了 Gmail API,你应该很好。

紫衣仙女

也许这个问题有点过时了,但我找到了一种从 python 上传文件到谷歌驱动器上的简单方法pip install gdrive-python然后,您必须允许脚本使用此命令在您的 Google 帐户上上传文件并按照说明操作:python -m drive about最后,上传文件:form gdrive import GDrivedrive = GDrive()drive.upload('path/to/file')有关 GitHub 存储库的更多信息:https ://github.com/vittoriopippi/gdrive-python

慕姐8265434

我找到了将文件上传到谷歌驱动器的解决方案。这里是:import requestsimport jsonurl = "https://www.googleapis.com/oauth2/v4/token"&nbsp; &nbsp; &nbsp; &nbsp; payload = "{\n\"" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "client_id\": \"CLIENT_ID" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "\",\n\"" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "client_secret\": \"CLIENT SECRET" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "\",\n\"" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "refresh_token\": \"REFRESH TOKEN" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "\",\n\"" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "grant_type\": \"refresh_token\"\n" \&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "}"&nbsp; &nbsp; &nbsp; &nbsp; headers = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'grant_type': 'authorization_code',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Content-Type': 'application/json'&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; response = requests.request("POST", url, headers=headers, data=payload)&nbsp; &nbsp; &nbsp; &nbsp; res = json.loads(response.text.encode('utf8'))&nbsp; &nbsp; &nbsp; &nbsp; headers = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Authorization": "Bearer %s" % res['access_token']&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; para = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "name": "file_path",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "parents": "google_drive_folder_id"&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; files = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 'file': open("./gb.png", "rb")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'file': ('mimeType', open("file_path", "rb"))&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; r = requests.post(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headers=headers,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; files=files&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; print(r.text)要生成客户端 ID、客户端密码和刷新令牌,您可以点击链接:-单击此处
随时随地看视频慕课网APP

相关分类

Python
我要回答