39

您能否提供一个 Python 示例,说明如何根据其键和工作表 ID ( gid) 下载 Google Docs 电子表格?我不能。

我已经搜索了 API 的版本 1、2 和 3。我没有运气,我无法弄清楚他们复杂的类似于 ATOM 的提要 API,gdata.docs.service.DocsService._DownloadFile私有方法说我未经授权,我不想自己编写一个完整的谷歌登录身份验证系统。由于沮丧,我正要刺伤自己的脸。

我有一些电子表格,我想像这样访问它们:

username = 'mygooglelogin@gmail.com'
password = getpass.getpass()

def get_spreadsheet(key, gid=0):
    ... (help!) ...

for row in get_spreadsheet('5a3c7f7dcee4b4f'):
    cell1, cell2, cell3 = row
    ...

请救救我的脸。


更新 1:我尝试了以下方法,但没有任何组合Download()Export()似乎有效。(DocsService 此处的文档)

import gdata.docs.service
import getpass
import os
import tempfile
import csv

def get_csv(file_path):
  return csv.reader(file(file_path).readlines())

def get_spreadsheet(key, gid=0):
  gd_client = gdata.docs.service.DocsService()
  gd_client.email = 'xxxxxxxxx@gmail.com'
  gd_client.password = getpass.getpass()
  gd_client.ssl = False
  gd_client.source = "My Fancy Spreadsheet Downloader"
  gd_client.ProgrammaticLogin()

  file_path = tempfile.mktemp(suffix='.csv')
  uri = 'http://docs.google.com/feeds/documents/private/full/%s' % key
  try:
    entry = gd_client.GetDocumentListEntry(uri)

    # XXXX - The following dies with RequestError "Unauthorized"
    gd_client.Download(entry, file_path)

    return get_csv(file_path)
  finally:
    try:
      os.remove(file_path)
    except OSError:
      pass
4

13 回答 13

38

https://github.com/burnash/gspread库是一种更新、更简单的与 Google 电子表格交互的方式,而不是旧的答案,即表明该gdata库不仅太低级,而且过于 -复杂。

您还需要创建和下载(JSON 格式)服务帐户密钥:https ://console.developers.google.com/apis/credentials/serviceaccountkey

以下是如何使用它的示例:

import csv
import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)

docid = "0zjVQXjJixf-SdGpLKnJtcmQhNjVUTk1hNTRpc0x5b9c"

client = gspread.authorize(credentials)
spreadsheet = client.open_by_key(docid)
for i, worksheet in enumerate(spreadsheet.worksheets()):
    filename = docid + '-worksheet' + str(i) + '.csv'
    with open(filename, 'wb') as f:
        writer = csv.writer(f)
        writer.writerows(worksheet.get_all_values())
于 2013-08-18T06:22:42.063 回答
20

如果有人遇到这个寻找快速解决方案,这里是另一个(当前)不依赖 gdata 客户端库的工作解决方案:

#!/usr/bin/python

import re, urllib, urllib2

class Spreadsheet(object):
    def __init__(self, key):
        super(Spreadsheet, self).__init__()
        self.key = key

class Client(object):
    def __init__(self, email, password):
        super(Client, self).__init__()
        self.email = email
        self.password = password

    def _get_auth_token(self, email, password, source, service):
        url = "https://www.google.com/accounts/ClientLogin"
        params = {
            "Email": email, "Passwd": password,
            "service": service,
            "accountType": "HOSTED_OR_GOOGLE",
            "source": source
        }
        req = urllib2.Request(url, urllib.urlencode(params))
        return re.findall(r"Auth=(.*)", urllib2.urlopen(req).read())[0]

    def get_auth_token(self):
        source = type(self).__name__
        return self._get_auth_token(self.email, self.password, source, service="wise")

    def download(self, spreadsheet, gid=0, format="csv"):
        url_format = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=%s&exportFormat=%s&gid=%i"
        headers = {
            "Authorization": "GoogleLogin auth=" + self.get_auth_token(),
            "GData-Version": "3.0"
        }
        req = urllib2.Request(url_format % (spreadsheet.key, format, gid), headers=headers)
        return urllib2.urlopen(req)

if __name__ == "__main__":
    import getpass
    import csv

    email = "" # (your email here)
    password = getpass.getpass()
    spreadsheet_id = "" # (spreadsheet id here)

    # Create client and spreadsheet objects
    gs = Client(email, password)
    ss = Spreadsheet(spreadsheet_id)

    # Request a file-like object containing the spreadsheet's contents
    csv_file = gs.download(ss)

    # Parse as CSV and print the rows
    for row in csv.reader(csv_file):
        print ", ".join(row)
于 2012-01-25T16:22:34.910 回答
18

您可以尝试使用文档的导出电子表格部分中描述的 AuthSub 方法。

为电子表格服务获取单独的登录令牌并将其替换为导出。将此添加到get_spreadsheet代码中对我有用:

import gdata.spreadsheet.service

def get_spreadsheet(key, gid=0):
    # ...
    spreadsheets_client = gdata.spreadsheet.service.SpreadsheetsService()
    spreadsheets_client.email = gd_client.email
    spreadsheets_client.password = gd_client.password
    spreadsheets_client.source = "My Fancy Spreadsheet Downloader"
    spreadsheets_client.ProgrammaticLogin()

    # ...
    entry = gd_client.GetDocumentListEntry(uri)
    docs_auth_token = gd_client.GetClientLoginToken()
    gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken())
    gd_client.Export(entry, file_path)
    gd_client.SetClientLoginToken(docs_auth_token) # reset the DocList auth token

请注意,我也使用了Export,因为Download似乎只提供 PDF 文件。

于 2010-07-30T23:28:24.337 回答
6

(2016 年 7 月)用当前术语改写:“如何使用 Python从 Google Drive下载 CSV 或 XLSX 格式的 Google Sheet ?”。(Google Docs 现在仅指基于云的文字处理器/文本编辑器,它不提供对 Google Sheets 电子表格的访问。)

首先,所有其他答案都已经过时或将会过时,因为它们使用GData(“ Google 数据”) ProtocolClientLoginAuthSub所有这些都已被弃用。对于使用 Google Sheets API v3 或更早版本的所有代码或库也是如此。

现代 Google API 访问使用 API 密钥(用于访问公共数据)、OAuth2 客户端 ID(用于访问用户拥有的数据)或服务帐户(用于访问应用程序/在云中拥有的数据)主要使用Google Cloud 客户端库进行用于非 GCP API 的GCP API 和Google API 客户端库。对于此任务,Python 将是后者

为此,您的代码需要获得对Google Drive API的授权访问权限,可能需要查询要下载的特定表格,然后执行实际导出。由于这可能是一种常见的操作,我写了一篇博文,分享了一个代码片段,可以为您完成此操作。如果您希望进一步了解这一点,我还有另外一对帖子以及一个视频,其中概述了如何将文件上传到 Google Drive 和从 Google Drive 下载文件。

请注意,还有一个更新的Google Sheets API v4,但它主要用于面向电子表格的操作,即插入数据、读取电子表格行、单元格格式、创建图表、添加数据透视表等,而不是基于文件的请求,如导出Drive API 是正确使用的 API。

我写了一篇博客文章,演示了从 Drive 将 Google Sheet 导出为 CSV。脚本的核心部分:

# setup
FILENAME = 'inventory'
SRC_MIMETYPE = 'application/vnd.google-apps.spreadsheet'
DST_MIMETYPE = 'text/csv'
DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))

# query for file to export
files = DRIVE.files().list(
    q='name="%s" and mimeType="%s"' % (FILENAME, SRC_MIMETYPE), orderBy='modifiedTime desc,name').execute().get('files', [])

# export 1st match (if found)
if files:
    fn = '%s.csv' % os.path.splitext(files[0]['name'].replace(' ', '_'))[0]
    print('Exporting "%s" as "%s"... ' % (files[0]['name'], fn), end='')
    data = DRIVE.files().export(fileId=files[0]['id'], mimeType=DST_MIMETYPE).execute()
    if data:
        with open(fn, 'wb') as f:
            f.write(data)
        print('DONE')

要了解有关在 Python 中使用 Google 表格的更多信息,请参阅对类似问题的回答。您还可以下载 XLSX 和Drive 支持的其他格式的工作表。

如果您完全不熟悉 Google API,那么您需要退后一步,先查看这些视频:

如果您已经有 G Suite API 的使用经验并希望观看更多有关使用这两种 API 的视频:

于 2016-07-11T23:10:24.497 回答
3

这不再适用于 gdata 2.0.1.4:

gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken())

相反,您必须这样做:

gd_client.SetClientLoginToken(gdata.gauth.ClientLoginToken(spreadsheets_client.GetClientLoginToken()))
于 2011-03-24T17:24:55.763 回答
2

以下代码适用于我的情况(Ubuntu 10.4,python 2.6.5 gdata 2.0.14)

import gdata.docs.service
import gdata.spreadsheet.service
gd_client = gdata.docs.service.DocsService()
gd_client.ClientLogin(email,password)
spreadsheets_client = gdata.spreadsheet.service.SpreadsheetsService()
spreadsheets_client.ClientLogin(email,password)
#...
file_path = file_path.strip()+".xls"
docs_token = gd_client.auth_token
gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken())
gd_client.Export(entry, file_path)  
gd_client.auth_token = docs_token
于 2011-05-07T23:00:38.730 回答
2

我编写了pygsheets作为 gspread 的替代品,但使用的是 google api v4。它有一种export导出电子表格的方法。

import pygsheets

gc = pygsheets.authorize()

# Open spreadsheet and then workseet
sh = gc.open('my new ssheet')
wks = sh.sheet1

#export as csv
wks.export(pygsheets.ExportType.CSV)
于 2016-12-11T11:30:34.790 回答
1

通过删除不必要的面向对象,我进一步简化了@Cameron 的答案。这使得代码更小更容易理解。我还编辑了网址,这可能会更好。

#!/usr/bin/python
import re, urllib, urllib2

def get_auth_token(email, password):
    url = "https://www.google.com/accounts/ClientLogin"
    params = {
        "Email": email, "Passwd": password,
        "service": 'wise',
        "accountType": "HOSTED_OR_GOOGLE",
        "source": 'Client'
    }
    req = urllib2.Request(url, urllib.urlencode(params))
    return re.findall(r"Auth=(.*)", urllib2.urlopen(req).read())[0]

def download(spreadsheet, worksheet, email, password, format="csv"):
    url_format = 'https://docs.google.com/spreadsheets/d/%s/export?exportFormat=%s#gid=%s'

    headers = {
        "Authorization": "GoogleLogin auth=" + get_auth_token(email, password),
        "GData-Version": "3.0"
    }
    req = urllib2.Request(url_format % (spreadsheet, format, worksheet), headers=headers)
    return urllib2.urlopen(req)


if __name__ == "__main__":
    import getpass
    import csv

    spreadsheet_id = ""             # (spreadsheet id here)
    worksheet_id = ''               # (gid here)
    email = ""                      # (your email here)
    password = getpass.getpass()

    # Request a file-like object containing the spreadsheet's contents
    csv_file = download(spreadsheet_id, worksheet_id, email, password)

    # Parse as CSV and print the rows
    for row in csv.reader(csv_file):
        print ", ".join(row)
于 2014-10-12T00:45:58.620 回答
1

使用工作表从 google doc 下载电子表格非常简单。

您可以按照上的详细文档

https://pypi.org/project/gsheets/

或按照以下步骤操作。我建议通读文档以获得更好的覆盖范围。

  1. 点安装 gsheets

  2. 使用您要访问其电子表格的 Google 帐户登录 Google Developers Console。创建(或选择)一个项目并启用 Drive API 和 Sheets API(在 Google Apps API 下)。

  3. 转到项目的凭据并创建新凭据 > OAuth 客户端 ID > 类型为其他。在您的 OAuth 2.0 客户端 ID 列表中,单击您刚刚创建的客户端 ID 的下载 JSON。在您的主目录(用户目录)中将文件另存为 client_secrets.json。

  4. 使用以下代码片段。

    from gsheets import Sheets
    sheets = Sheets.from_files('client_secret.json')
    print(sheets) # will ensure authenticate connection
    
    s = sheets.get("{SPREADSHEET_URL}")
    print(s) # will ensure your file is accessible 
    
    s.sheets[1].to_csv('Spam.csv', encoding='utf-8', dialect='excel') # will download the file as csv
于 2020-07-09T20:45:21.773 回答
1

我正在使用这个: curl ' https://docs.google.com/spreadsheets/d/1-lqLuYJyHAKix-T8NR8wV8ZUUbVOJrZTysccid2-ycs/gviz/tq?tqx=out:csv ' 在设置为公开可读的工作表上。

因此,如果您可以使用公共工作表,您将需要一个 python 版本的 curl。

如果您的工作表有一些您不想显示的选项卡,请创建一个新工作表,然后将要发布的范围导入到其上的选项卡中。

于 2020-01-13T16:40:30.733 回答
0

Gspread 确实是对 GoogleCL 和 Gdata 的一个很大的改进(我已经使用了这两个,谢天谢地,为了支持 Gspread,它们被淘汰了)。我认为这段代码比之前获取工作表内容的答案更快:

username = 'sdfsdfsds@gmail.com'
password = 'sdfsdfsadfsdw'
sheetname = "Sheety Sheet"

client = gspread.login(username, password)
spreadsheet = client.open(sheetname)

worksheet = spreadsheet.sheet1
contents = []
for rows in worksheet.get_all_values():
    contents.append(rows)
于 2014-09-14T03:15:47.040 回答
0

这不是一个完整的答案,但Andreas Kahler使用 Google Docs + Google App Engline + Python 编写了一个有趣的 CMS 解决方案。在该领域没有任何经验,我无法确切了解代码的哪一部分可能对您有用,但请检查一下。我知道它与 Google Docs 帐户交互并播放文件,所以我感觉你会认出发生了什么。它至少应该为您指明正确的方向。

Google AppEngine + Google Docs + 一些 Python = 简单的 CMS

于 2010-07-30T16:58:42.040 回答
0

(Mar 2019, Python 3) My data is usually not sensitive and I use usually table format similar to CSV.

In such case, one can simply publish to the web the sheet and than use it as a CSV file on a server.

(One publishes it using File -> Publish to the web ... -> Sheet 1 -> Comma separated values (.csv) -> Publish).

import csv
import io
import requests

url = "https://docs.google.com/spreadsheets/d/e/<GOOGLE_ID>/pub?gid=0&single=true&output=csv"  # you can get the whole link in the 'Publish to the web' dialog
r = requests.get(url)
r.encoding = 'utf-8'
csvio = io.StringIO(r.text, newline="")
data = []
for row in csv.DictReader(csvio):
    data.append(row)
于 2019-03-05T00:59:54.717 回答