为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕哥9229398 2022-07-26 10:46:58
我尝试使用 Python 脚本从本地系统将文件上传到 Google Drive,但我不断收到 HttpError 403。脚本如下:from googleapiclient.http import MediaFileUploadfrom googleapiclient import discoveryimport httplib2import authSCOPES = "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 requestinghttps://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&alt=json&fields=id returned "Insufficient Permission: Request had insufficient authentication scopes.">我在代码中使用了正确的范围还是遗漏了什么?我还尝试了我在网上找到的一个脚本,它工作正常,但问题是它需要一个静态令牌,该令牌会在一段时间后过期。那么如何动态刷新令牌呢?这是我的代码:import jsonimport requestsheaders = {    "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)
查看完整描述

6 回答

?
墨色风雨

TA贡献1853条经验 获得超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 成功地将文件上传和下载到谷歌驱动器。


查看完整回答
反对 回复 2022-07-26
?
开满天机

TA贡献1786条经验 获得超13个赞

“权限不足:请求的身份验证范围不足。”

意味着您已通过身份验证的用户尚未授予您的应用程序执行您尝试执行的操作的权限。

files.create方法要求您已使用以下范围之一对用户进行身份验证

//img1.sycdn.imooc.com//62df55c70001311605730313.jpg

而您的代码似乎确实使用了完整的驱动范围。我怀疑发生的事情是您已经对用户进行了身份验证,然后更改了代码中的范围,并且没有促使用户再次登录并同意。您需要从您的应用程序中删除用户的同意,方法是让他们直接在他们的谷歌帐户中删除它,或者只是删除您存储在应用程序中的凭据。这将强制用户再次登录。


谷歌登录还有一个批准提示强制选项,但我不是 python 开发人员,所以我不完全确定如何强制。它应该类似于下面的 prompt='consent' 行。


flow = OAuth2WebServerFlow(client_id=CLIENT_ID,

                           client_secret=CLIENT_SECRET,

                           scope='https://spreadsheets.google.com/feeds '+

                           'https://docs.google.com/feeds',

                           redirect_uri='http://example.com/auth_return',

                           prompt='consent')

同意屏幕

如果操作正确,用户应该会看到这样的屏幕

//img1.sycdn.imooc.com//62df55d1000144ee05600477.jpg

提示他们授予您对其云端硬盘帐户的完全访问权限


令牌泡菜

如果您在https://developers.google.com/drive/api/v3/quickstart/python遵循谷歌教程,则需要删除包含用户存储同意的 token.pickle。


if os.path.exists('token.pickle'):

    with open('token.pickle', 'rb') as token:

        creds = pickle.load(token)


查看完整回答
反对 回复 2022-07-26
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

您可以使用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):

    media = MediaFileUpload(filename, mimetype=mimetype, resumable=resumable, chunksize=chunksize)

    # Add all the writable properties you want the file to have in the body!

    body = {"name": upload_filename} 

    request = drive_service.files().create(body=body, media_body=media).execute()

    if getFileByteSize(filename) > chunksize:

        response = None

        while response is None:

            chunk = request.next_chunk()

            if chunk:

                status, response = chunk

                if status:

                    print("Uploaded %d%%." % int(status.progress() * 100))

    print("Upload Complete!")

现在传入参数并调用函数...


# Upload file

upload_file(drive_service, 'my_local_image.png', 'image/png', 'my_imageination.png' )

您将在 Google Drive 根文件夹中看到名为my_imageination.png的文件。


有关 Drive API v3 服务和可用方法的更多信息,请点击此处。


getFileSize()功能:


def getFileByteSize(filename):

    # Get file size in python

    from os import stat

    file_stats = stat(filename)

    print('File Size in Bytes is {}'.format(file_stats.st_size))

    return file_stats.st_size

上传到驱动器中的某些文件夹很容易...

只需在请求正文中添加父文件夹 ID。


这是File 的属性。

//img1.sycdn.imooc.com//62df55e80001f40d08600156.jpg

例子:

request_body = {

  "name": "getting_creative_now.png",

  "parents": ['myFiRsTPaRentFolderId',

              'MyOtherParentId',

              'IcanTgetEnoughParentsId'],

}


查看完整回答
反对 回复 2022-07-26
?
九州编程

TA贡献1785条经验 获得超4个赞

回答:

删除您的token.pickle文件并重新运行您的应用程序。

更多信息:

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


查看完整回答
反对 回复 2022-07-26
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

也许这个问题有点过时了,但我找到了一种从 python 上传文件到谷歌驱动器上的简单方法


pip install gdrive-python

然后,您必须允许脚本使用此命令在您的 Google 帐户上上传文件并按照说明操作:


python -m drive about

最后,上传文件:


form gdrive import GDrive


drive = GDrive()

drive.upload('path/to/file')

有关 GitHub 存储库的更多信息:https ://github.com/vittoriopippi/gdrive-python


查看完整回答
反对 回复 2022-07-26
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

我找到了将文件上传到谷歌驱动器的解决方案。这里是:


import requests

import json

url = "https://www.googleapis.com/oauth2/v4/token"


        payload = "{\n\"" \

                  "client_id\": \"CLIENT_ID" \

                  "\",\n\"" \

                  "client_secret\": \"CLIENT SECRET" \

                  "\",\n\"" \

                  "refresh_token\": \"REFRESH TOKEN" \

                  "\",\n\"" \

                  "grant_type\": \"refresh_token\"\n" \

                  "}"

        headers = {

            'grant_type': 'authorization_code',

            'Content-Type': 'application/json'

        }


        response = requests.request("POST", url, headers=headers, data=payload)


        res = json.loads(response.text.encode('utf8'))



        headers = {

            "Authorization": "Bearer %s" % res['access_token']

        }

        para = {

            "name": "file_path",

            "parents": "google_drive_folder_id"

        }

        files = {

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

            # 'file': open("./gb.png", "rb")

            'file': ('mimeType', open("file_path", "rb"))

        }

        r = requests.post(

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

            headers=headers,

            files=files

        )

        print(r.text)

要生成客户端 ID、客户端密码和刷新令牌,您可以点击链接:-单击此处


查看完整回答
反对 回复 2022-07-26
  • 6 回答
  • 0 关注
  • 389 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号