Google API,名称io未定义 修改点:修改后的脚本:注意:参考文献:

因此,通过遵循Google驱动器API文档,我试图创建一个程序,该程序将在我在Google驱动程序上保存的所有电子表格中查找并下载它们。

问题是我一直在获取名称'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()

所以...我在做什么错了?

fql920011429 回答:Google API,名称io未定义 修改点:修改后的脚本:注意:参考文献:

  • 您要使用带有python的google-api-python-client将Google Spreadsheet下载为XLSX文件。

如果我的理解正确,那么这个答案如何?请认为这只是几个答案之一。

我认为从您的错误消息中可以发现,授权过程已经完成,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 iofrom googleapiclient.http import MediaIoBaseDownload时,我认为发生了insufficient authentication scopes的错误。因此,请将范围从https://www.googleapis.com/auth/drive.metadata.readonly修改为https://www.googleapis.com/auth/drive.readonly
    • 这时,请删除token.pickle文件,然后通过运行脚本重新授权范围。由此,反映了新的范围。请注意这一点。
  • 如果Google云端硬盘中除Google Spreadsheet以外的文件,我认为在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()

注意:

  • 如果要下载10个以上的文件,请修改pageSize=10。最大值为1000。如果要下载的文件超过1000,则需要使用pageToken修改脚本。请注意这一点。
  • 如果运行修改后的脚本时发生错误,请确认items的{​​{1}}的值。如果items = results.get('files',[])没有值,则意味着items不返回文件列表。

参考文献:

如果我误解了您的问题,而这不是您想要的结果,我深表歉意。

本文链接:https://www.f2er.com/3164136.html

大家都在问