Python 3.x Google API,未定义名称io
因此,通过遵循GoogleDriveAPI文档,我试图创建一个程序,在GoogleDriver上查看所有保存的电子表格并下载它们 问题是我一直得到的名称“io”没有定义Python 3.x Google API,未定义名称io,python-3.x,google-api,google-drive-api,Python 3.x,Google Api,Google Drive Api,因此,通过遵循GoogleDriveAPI文档,我试图创建一个程序,在GoogleDriver上查看所有保存的电子表格并下载它们 问题是我一直得到的名称“io”没有定义 from __future__ import print_function import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
# If modifying these scopes, delete the file token.pickle.
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.pickle 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.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# 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.pickle', 'wb') as token:
pickle.dump(creds, token)
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.')
else:
print('Files:')
for item in items:
print(u'{0} ({1})'.format(item['name'], item['id']))
file_id = item['id']
request = service.files().export_media(fileId=file_id,
mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
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))
if __name__ == '__main__':
main()
所以。。。我做错了什么
您希望使用带有python的Google api python客户端将Google电子表格作为XLSX文件下载。
如果我的理解是正确的,那么这个答案呢?请把这看作是几个答案中的一个
我认为,从您的错误消息中,可以发现授权过程已经完成,token.pickle已经创建,service.files.list已经工作。在这个回答中,我想是这样的。如果您还不能创建token.pickle文件,请再次检查
修改点:
关于未定义名称“io”的错误,请将导入io添加到脚本中。通过此操作,可以删除此错误消息。
但是在脚本中,有更多的修改点。因此,请检查以下几点
我认为在添加导入io后,出现了一个名为“MediaIoBaseDownload”的错误。因此,也请添加从GoogleAppClient.http导入MediaIoBaseDownload。
在添加import io和from GoogleAppClient.http import MediaIoBaseDownload时,我认为出现了身份验证作用域不足的错误。因此,请从中修改范围https://www.googleapis.com/auth/drive.metadata.readonly 到https://www.googleapis.com/auth/drive.readonly.
此时,请删除token.pickle文件,并通过运行脚本重新授权作用域。由此,新的范围得以体现。请小心这个。
如果您的Google驱动器中存在除Google电子表格以外的文件,我认为service.files.export_media会出错。如果只想检索Google电子表格,可以使用搜索查询。在您的情况下,可以使用q=mimeType='application/vnd.google apps.spreadsheet'。
在脚本中,使用fh=io.BytesIO。在这种情况下,文件作为导出文件下载。但下载的文件不是在您的电脑中创建的。例如,如果要在您的电脑中创建下载的文件,请将fh=io.BytesIO修改为fh=io.FileIOitem['name']+'.xlsx',mode='wb'。
当上述修改点反映到脚本中时,它将变成如下所示
修改脚本:
在运行脚本之前,请删除token.pickle文件。这样,当您运行脚本时,将运行授权过程,当授权完成时,新范围将反映到访问令牌和刷新令牌
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import io # Added
from googleapiclient.http import MediaIoBaseDownload # Added
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.readonly'] # Modified
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.pickle 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.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# 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.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
# Call the Drive v3 API
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name)", q="mimeType='application/vnd.google-apps.spreadsheet'").execute() # Modified
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
for item in items:
print(u'{0} ({1})'.format(item['name'], item['id']))
file_id = item['id']
request = service.files().export_media(fileId=file_id,
mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
# fh = io.BytesIO()
fh = io.FileIO(item['name'] + '.xlsx', mode='wb') # If you want to create the downloaded file to your PC, please use this instead of "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))
if __name__ == '__main__':
main()
注:
如果要下载超过10个的文件,请修改pageSize=10。最大值为1000。如果要下载超过1000个文件,则需要使用pageToken修改脚本。请小心这个。
在这种情况下,可能会有用。
如果在运行修改后的脚本时出错,请确认items=results.get'files',[]的items值。如果items为no value,则表示service.files.list不返回文件列表。
参考资料:
如果我误解了你的问题,而这不是你想要的结果,我道歉