繁体   English   中英

表格 API:使用 Python 从电子表格中读取数据

[英]Sheets API: reading data from spreadsheet with Python

我正在尝试从共享到我个人 email 地址的 Google 电子表格中检索数据。 我在 json 文件中设置了一个服务帐户,如下所示:

{
  "type": "service_account",
  "project_id": "my-project-name",
  "private_key_id": "012345678901234567890123456789",
  "private_key": "-----BEGIN PRIVATE KEY-----\xxxxx\n-----END PRIVATE KEY-----\n",
  "client_email": "my-name@my-project-name.iam.gserviceaccount.com",
  "client_id": "9876543210",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/my-name%40my-project-name.iam.gserviceaccount.com"
}

我的代码的基本原理(见下文)是这样的:给定一个带有 url 的电子表格,它与我共享(--> spreadsheet_idsheet_id ),它找到选项卡名称( name ),并使用它来检索数据( data_values ) 最终转换为pd.DataFrame

现在我的问题是,当我在公开可用的在线电子表格上运行此 function 时,它工作正常,但每当我尝试在我有权访问但它不公开的电子表格上运行它时,它会失败并出现以下错误:

Error code: 403, PERMISSION_DENIED: The request is missing a valid API key

就好像服务帐户(链接到我的 Google 帐户,因此链接到我的个人电子邮件)无权访问与我的个人帐户共享的内容。 这是设计的情况吗? 我该如何克服呢? 我更喜欢自动解决方案,而不是必须单独手动设置每个电子表格的访问权限,以便与我的服务帐户地址共享它,而不是我的个人地址。

编辑:从那时起,我手动将我的服务帐户的 email 地址添加到其中一个文件中,并且它有效。 看来,服务帐户无法访问我的个人电子邮件文件,只能访问那些专门与服务帐户共享的文件? 然后我是否应该总是与我的服务帐户 email 地址共享每个文件?

代码:

def get_spreadsheet_data(name, spreadsheet_id, sheet_id, service_account_json_path, scope):

    creds = ServiceAccountCredentials.from_json_keyfile_name(service_account_json_path, scope)
    service = build('sheets', 'v4', credentials=creds)
    sheets = service.spreadsheets()

    # If name is not provided, generate it from spreadsheet_id
    if not name:
        a = sheets.get(
            spreadsheetId=spreadsheet_id,
            fields='sheets(properties(index,sheetId,title))'
        ).execute()
        name = [sheet['properties']['title'] for sheet in a['sheets'] \
                if int(sheet['properties']['sheetId']) == int(sheet_id)][0]
    
    data_table = sheets.values().get(spreadsheetId=spreadsheet_id, range=name).execute()
    data_values = data_table.get('values', [])
        
    df = pd.DataFrame(data_values)
    return df

出于文档目的发布此内容。

正如Tanaike 提到的,服务帐户和您的常规帐户是完全不同的帐户。

服务帐户本身只能访问与其共享(或由其创建)的文件,而不是与您的常规帐户共享的文件。

如官方文档中所述:

通常,当应用程序使用 Google API 处理自己的数据而不是用户的数据时,应用程序会使用服务帐户。

如果您有 Workspace 帐户,您可以使用服务帐户代表您域中的其他用户(例如您的常规帐户):请参阅将域范围的权限委托给服务帐户 否则,无法使用您的服务帐户访问用户文件。

参考:

暂无
暂无

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

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