所以,通过遵循google drive API文档,我试图创建一个程序,该程序将在google driver上所有保存的电子表格中查找并下载。
问题是我一直没有得到名字'io'的定义
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()
所以...我在做什么错?
如果我的理解是正确的,那么这个答案怎么样?请认为这只是几个答案之一。
我认为从您的错误消息中可以发现,授权过程已完成,token.pickle
已创建且service.files().list()
有效。在这个答案中,我想是这样。如果您仍无法创建token.pickle
文件,请再次检查the Quickstart。
name 'io' is not defined
的错误,请在脚本中添加import io
。这样,可以删除此错误消息。但是在您的脚本中,还有更多修改点。因此,请检查以下几点。
import io
之后,会出现name 'MediaIoBaseDownload' is not defined
错误。所以也请添加from googleapiclient.http import MediaIoBaseDownload
。import io
和from googleapiclient.http import MediaIoBaseDownload
时,我认为发生了insufficient authentication scopes
错误。因此,请将范围从https://www.googleapis.com/auth/drive.metadata.readonly
修改为https://www.googleapis.com/auth/drive.readonly
。token.pickle
文件,然后通过运行脚本重新授权范围。由此,反映了新的范围。请注意这一点。service.files().export_media()
发生了错误。当您只想检索Google Spreadsheet时,可以使用搜索查询。根据您的情况,可以使用q="mimeType='application/vnd.google-apps.spreadsheet'"
。fh = io.BytesIO()
。在这种情况下,文件将作为导出下载。但是下载的文件未在您的PC中创建。例如,如果要将下载的文件创建到PC上,请将fh = io.BytesIO()
修改为fh = io.FileIO(item['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()
pageSize=10
。最大值为1000。如果要下载的文件超过1000,则需要使用pageToken
修改脚本。请注意这一点。items
的items = results.get('files', [])
的值。 items
没有值时,表示service.files().list()
不返回文件列表。如果我误解了您的问题,而这不是您想要的结果,我深表歉意。