我遵循Google给出的quickstart使用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 provides下载文件的功能(已编辑的文件路径和一些注释):
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或任何其他凭证,但是如果需要更多信息,请告诉我!
答案 0 :(得分:2)
Only files with binary content can be downloaded. Use Export with Google Docs files.
错误的原因如果我的理解正确,那么这个答案如何?
get_media
方法下载Google Docs文件时,会发生此类错误。
get_media
方法,可以下载Google Docs之外的文件(电子表格,文档,幻灯片等)。export_media
方法。
为了避免该问题,如何进行以下修改?
从: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')
text/csv
。如果我误解了您的问题,而这不是您想要的方向,我深表歉意。
关于更改访问令牌范围的方法,请重命名或删除脚本中的storage.json
文件,然后再次运行该脚本。这样,您可以重新授权新作用域,并创建包含令牌的新文件。您可以在新的作用域中使用访问令牌。
答案 1 :(得分:0)
我正在使用它,并且可以在以下库中使用:
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