如何将Google表格文件从Python 3(或2)保存为CSV?

时间:2013-02-28 15:01:57

标签: python csv google-drive-api google-api-python-client google-sheets-api

我正在寻找一种简单的方法来保存源自已发布的Google表格文档的csv文件?自发布以来,可以通过直接链接访问(在下面的示例中有意修改)。

我启动链接后,所有浏览器都会提示我保存csv文件。

既不:

DOC_URL = 'https://docs.google.com/spreadsheet/ccc?key=0AoOWveO-dNo5dFNrWThhYmdYW9UT1lQQkE&output=csv'    

f = urllib.request.urlopen(DOC_URL)
cont = f.read(SIZE)
f.close()
cont = str(cont, 'utf-8')
print(cont)

,也不是:

req = urllib.request.Request(DOC_URL)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.13 (KHTML, like Gecko) Chrome/24.0.1284.0 Safari/537.13')
f = urllib.request.urlopen(req)
print(f.read().decode('utf-8'))

打印除html内容之外的任何内容。

(阅读另一篇文章后尝试了第二个版本:Download google docs public spreadsheet to csv with python。)

对我做错了什么的任何想法?我已经退出了我的Google帐户,如果这对任何东西都有价值,但这可以在我尝试过的任何浏览器中使用。据我所知,Google Docs API还没有在Python 3上移植,并且考虑到我个人使用的小项目的“玩具”大小,如果从一开始就使用它,甚至没有多大意义。我可以绕过它。

在第二次尝试中,我离开了“用户代理”,因为我认为可能被认为来自脚本的请求(b / c没有识别信息)可能被忽略,但它没有成为差。

2 个答案:

答案 0 :(得分:6)

虽然requests库是来自Python的HTTP请求的黄金标准,但这种下载方式(虽然尚未弃用)不太可能持续,特别是指使用链接,管理cookie和重定向等。更喜欢链接的原因之一是它不太安全,通常这种访问需要授权。相反,当前接受的将Google表格导出为CSV的方式是使用 Google Drive API

为什么选择Drive API?这不应该是Sheets API的东西吗?好吧,Sheets API用于电子表格定向功能,即数据格式化,列调整大小,创建图表,单元格验证等,而Drive API用于文件面向导向的功能,即导入/导出,复制,重命名等。

下面是complete cmd-line solution。 (如果您不做Python,可以将其用作伪代码并选择Google APIs Client Libraries支持的任何语言。)对于代码段,假设最新的Sheet名为inventory(旧文件)忽略该名称并且DRIVE是API服务端点:

FILENAME = 'inventory'
SRC_MIMETYPE = 'application/vnd.google-apps.spreadsheet'
DST_MIMETYPE = 'text/csv'

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

# if found, export Sheets file as CSV
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 non-empty file
    if data:
        with open(fn, 'wb') as f:
            f.write(data)
        print('DONE')

如果您的工作表很大,则可能需要将其导出为块 - 请参阅this page了解如何 。如果您通常对Google API不熟悉,我会为您提供一个(有点过时但用户友好的)intro video。 (之后有2个视频也可能有用。)

答案 1 :(得分:4)

Google通过一系列Cookie设置302重定向来响应初始请求。如果您不在请求之间存储和重新提交cookie,它会将您重定向到登录页面。

因此,问题不在于User-Agent标头,而是默认情况下,urllib.request.urlopen不存储cookie,但它将遵循HTTP 302重定向。

以下代码适用于DOC_URL指定位置的公开电子表格:

>>> from http.cookiejar import CookieJar
>>> from urllib.request import build_opener, HTTPCookieProcessor
>>> opener = build_opener(HTTPCookieProcessor(CookieJar()))
>>> resp = opener.open(DOC_URL)
>>> # should really parse resp.getheader('content-type') for encoding.
>>> csv_content = resp.read().decode('utf-8')

告诉你如何在vanilla python中做到这一点,我现在要说正确的方法是使用最优秀的 requests library 。它是 extremely well documented ,让完成这些任务非常愉快。

例如,要使用csv_content库获取与上述相同的requests,就像这样简单:

>>> import requests
>>> csv_content = requests.get(DOC_URL).text

该单行更清楚地表达了您的意图。它更容易编写,更易于阅读。做你自己 - 和其他任何分享你的代码库的人 - 一个忙,只需使用requests