簡體   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