2010-07-20 90 views
24

您能否提供一个Python示例来说明如何下载Google文档电子表格(gid)?我不能。使用Python从Google Docs下载电子表格

我已经淘汰了API的版本1,2和3。我没有运气,我无法弄清楚他们已编译好的ATOM类似的API,gdata.docs.service.DocsService._DownloadFile私有方法说我是未经授权的,我不想自己写一个完整的Google登录认证系统。由于沮丧,我正要刺伤自己。

我有几个电子表格,我想访问他们像这样:

username = '[email protected]' 
password = getpass.getpass() 

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

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

请救救我的脸。


更新1:我试过以下,但没有Download()Export()组合似乎工作。 (Google文件DocsServicehere

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 = '[email protected]' 
    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 
+1

莫非[此](http://stackoverflow.com/questions/2925985/syntaxerror-using-gdata-python-client-to-access-google-book-search-data-api/3013945#3013945 )是你的问题? – sje397 2010-07-20 07:37:35

+0

试过了 - 谢谢!似乎帮助我通过登录问题。 – 2010-07-30 05:37:59

回答

17

如果有人遇到这种寻找一个快速解决,这里的another (currently) working solution不重LY在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) 
+1

真棒 - 一个很好的可重用的例子! – MrColes 2012-05-02 18:27:57

+0

这应该是选择的解决方案。去除gdata依赖是一个巨大的优势,你甚至可以将它打包成一个可以用作控制台应用程序和库的方式。我在get_auth_token请求周围添加了异常处理,但只有在遇到不正确的密码时才能输出有意义的消息。 – 2013-01-29 22:24:31

+0

是否有理由循环使用'csv_file'对象?为什么不只是'打印csv_file.read()' - csv in,csv out! – Spacedman 2013-05-02 11:06:46

0

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

Google AppEngine + Google Docs + Some Python = Simple CMS

15

您可以尝试使用文档的Exporting Spreadsheets部分中描述的方法的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文件。

+6

OMGITWORKS!掌声!站在OVATION! KICKASSEDNESS的认证密封!谢谢你,先生!我向你提供不低于FIFTY Stack Overflow积分的成熟奖励!把他们,先生 - 带他们和活的生活​​,因为它应该是活的! – 2010-07-31 06:24:10

+0

如果我可以添加赏金,我也会这样做。这只是挽救了我的工作生活。非常感谢! – Mizmor 2012-06-26 21:45:13

+2

A [更好的解决方案](http://stackoverflow.com/a/18296318/462302)现已可用,因为此答案最初被接受。 – aculich 2013-08-18 06:27:05

3

此不再工作作为GDATA 2.0.1.4的:

gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken()) 

相反,你必须做的:

gd_client.SetClientLoginToken(gdata.gauth.ClientLoginToken(spreadsheets_client.GetClientLoginToken())) 
+0

你可以走另一条路吗?使用gd_client登录,然后将电子表格客户端传递给令牌? – michael 2011-06-20 22:05:40

2

下面的代码工作在我的情况(Ubuntu的10.4,蟒蛇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 
24

https://github.com/burnash/gspread库是与谷歌电子表格进行交互,而不是旧的答案,这样该建议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()) 
+0

刚刚检查出来。看起来不错,我会将其标记为默认值。真棒! – 2013-08-18 21:11:03

+2

刚刚使用过这个,好东西! PS - 你可以改变方法来使用文档名称,而不是很好的键。 – 2013-09-23 20:29:55

+1

这只是加载所有的工作表。是否有可能通过gid加载工作表,而不是索引或名称? – d12frosted 2015-04-02 11:48:29

0

Gspread确实是一个很大的进步了GoogleCL和Gdata(我已经使用过这两种产品,并且很幸运地停止使用Gspread)。我认为,这个代码是比以前的答案更快拿到表的内容:

username = '[email protected]' 
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) 
1

我已经简化@卡梅隆的回答更进一步,通过删除不必要的面向对象。这使代码更小,更易于理解。我也编辑了网址,这可能会更好。

#!/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) 
+0

这个解决方案已经过时并且不起作用,就像所有的答案一样,你需要使用oauth2.0 – Richard 2016-07-16 06:34:37

3

(JUL 2016)当前术语的改写: “如何下载从使用Python谷歌驱动 CSV格式谷歌的表?”。 (Google Docs现在仅指基于云端的文字处理器/文本编辑器,它不提供对Google表格电子表格的访问权限。)

首先,所有其他答案都非常过时或将会因为他们使用老GData(” Google Data") ProtocolClientLogin,或AuthSub,所有这些都被废弃了。同样是为使用谷歌表API V3或所有代码或库真老。发生

现代谷歌API访问使用API​​密钥或OAuth2授权,主要包括Google APIs Client Libraries,包括the one for Python(不,您不必为了访问API而构建整个授权系统......请参阅下面的博客帖子。)

要执行OP中/由OP请求的任务,您可以使用Google Drive API,或许查询要下载的特定工作表,然后执行实际的导出。由于这可能是一种常见操作,我写了一个blogpost共享代码片段,为您做到这一点。如果您想进一步追求这一点,我还有一对posts以及一个视频,概述了如何将文件上传到Google云端硬盘和从云端硬盘下载文件。

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

要查看从Drive导出Google表格为CSV的示例,请查看我写的this blog post;要详细了解如何在Python中使用Google表格,请参阅this answer I wrote以获取类似问题。

0

(12月16日)尝试另一个库我写道: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) 
相关问题