繁体   English   中英

尽管添加了正确的范围,但带有 Python 的 Google Drive API 不允许文件下载

[英]Google Drive API with Python not allowing file download despite correct scopes being added

我遵循了 Google 提供的使用 Python 的快速入门,并且我使用了 Google 提供的适当范围从驱动器https://www.googleapis.com/auth/drive.readonly下载文件,但我不断收到错误:

googleapiclient.errors.HttpError: https://www.googleapis.com/drive/v3/files/1RWpLGCWldcJyVqa0tIVlScg60ExEtcNIvJ7R9M8DuhM?alt=media 返回“只能下载包含二进制内容的文件。使用 Google Docs 文件导出。”

当我尝试运行代码来下载文件时。

我可以读取驱动器上的文件,但尽管我尽了最大的努力,但我似乎无法从驱动器下载特定的电子表格。 下面是我用于通过 API 建立连接的代码(已编辑的文件路径和一些注释):

 def gsuite_connect(): file_path = 'OMITTED/Loading' # Get what permissions the user (using the API) will need. This as been set to high level # access by default scopes = ['https://www.googleapis.com/auth/drive.readonly'] # Access the tokens for G Suite to access the Drive. Ensure that if this file previous exists, # that it is in the current working directory store = file.Storage(os.path.join(file_path, 'storage.json')) # Access the credentials for the Drive API creds = store.get() if not creds or creds.invalid: print("\\nUsing credentials found in client_id(secret).json") flow = client.flow_from_clientsecrets(os.path.join(file_path, 'client_id.json'), scopes) creds = tools.run_flow(flow, store) http = creds.authorize(Http()) drive = discovery.build('drive', 'v3', http=http) sheets = discovery.build('sheets', 'v4', http=http) return drive, sheets

这是我用于根据Google 提供的内容下载文件的功能(已编辑的文件路径和一些评论):

 def get_datalog(self): dir_path = 'OMITTED/Downloads' fname = "'FILENAME'" files = self.drive.files().list(q="name = {}".format(fname), fields="nextPageToken, files(id, name)").execute() items = files.get('files', []) # Error checking and subsequent downloading if file successfully found if not items: exit() else: # Change into the desired directory for storing the file and download file based on the # retrieved ID os.chdir(dir_path) file_id = items[0]['id'] # Request download service request = self.drive.files().get_media(fileId=file_id) fh = io.FileIO(fname, mode='w') downloader = MediaIoBaseDownload(fh, request) done = False while done is False: status, done = downloader.next_chunk() print("Download %d%%." % int(status.progress() * 100)) # Return the file path return os.path.join(dir_path, fname)

帮助将不胜感激! 我不想显示敏感文件,例如 client_id.json 或任何其他凭据,但如果您需要更多信息,请告诉我!

  • 您想使用 google-api-python-client 和 python 下载 Google Docs(在您的情况下,它是电子表格。)。
  • 您想知道Only files with binary content can be downloaded. Use Export with Google Docs files.的错误原因Only files with binary content can be downloaded. Use Export with Google Docs files. Only files with binary content can be downloaded. Use Export with Google Docs files.
  • 您已经可以使用 Drive API。

如果我的理解是正确的,这个答案怎么样?

改装要点:

  • 当通过get_media方法下载Google Docs 文件时,会发生此类错误。
    • get_media方法的情况下,可以下载 Google Docs 以外的文件(电子表格、文档、幻灯片等)。
  • 当您要下载 Google Docs 文件时,请使用export_media方法。
    • 在这种情况下,由于谷歌方面的规范,无法下载原始谷歌文档。 所以请将其转换为其他格式。 比如Spreadsheet,就是Excel格式、CSV格式等等。

修改后的脚本:

为了避免这个问题,下面的修改怎么样?

从:
 request = self.drive.files().get_media(fileId=file_id)
到:
 request = self.drive.files().export_media(fileId=file_id, mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
  • 在这种情况下,Google 电子表格将下载为 Excel 文件。 如果您想以 CSV text/csv下载,请将 mimeType 修改为text/csv

笔记:

  • 在这种情况下,它假设您要下载的 Google Docs 文件是您的或公开共享的。

参考:

如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

添加:

关于更改访问令牌范围的方法,请重命名或删除脚本中的storage.json文件,然后重新运行脚本。 这样,您可以为新范围重新授权,并创建包括令牌的新文件。 您可以将访问令牌与新范围一起使用。

我正在使用它,它适用于以下库:

google-auth-oauthlib==0.4.1
google-api-python-client
google-auth-httplib2

这是我正在使用的片段:

from apiclient import errors
from googleapiclient.http import MediaIoBaseDownload
from googleapiclient.discovery import build

def download_google_document_from_drive(self, file_id):
    try:

        request = self.service.files().get_media(fileId=file_id)
        fh = io.BytesIO()
        downloader = MediaIoBaseDownload(fh, request)
        done = False
        while done is False:
            status, done = downloader.next_chunk()
            print('Download %d%%.' % int(status.progress() * 100))
        return fh
    except Exception as e:
        print('Error downloading file from Google Drive: %s' % e)

您可以将文件流写入文件:

import xlrd
workbook = xlrd.open_workbook(file_contents=fh.getvalue())

至于范围,我使用以下片段:

def __init__(self):
  self.service = build('drive', 'v3',
                    credentials=self._service_account_credentials())

def _service_account_credentials(self.):
   service_account_key_path = os.getenv('GOOGLE_APPLICATION_CREDENTIALS')

   credentials = service_account.Credentials.from_service_account_file(
     service_account_key_path)
   scoped_credentials = credentials.with_scopes(
     ['https://www.googleapis.com/oauth2/v4/token'])
   signer_email = scoped_credentials.service_account_email
   signer = scoped_credentials.signer

   credentials = google.oauth2.service_account.Credentials(
     signer,
     signer_email,
     token_uri='https://www.googleapis.com/oauth2/v4/token'
   )
   return credentials

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM