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

7
我正在寻找一种简单的方法来保存源自已发布的Google Sheets文档的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内容之外的任何内容。

(在阅读了另一篇文章后尝试了第二个版本:使用Python下载Google Docs公共电子表格为CSV。)

我做错了什么?如果有价值的话,我已经退出了我的Google帐户,但这在我尝试过的任何浏览器中都可以工作。据我所知,Google Docs API尚未移植到Python 3,并且鉴于我的小型个人项目的“玩具”规模,从一开始就使用它甚至也没有太多意义,如果我可以绕过它。

在第二次尝试中,我保留了“User-Agent”,因为我认为可能会忽略来自脚本(因为没有身份信息)的请求,但这没有任何区别。


1
这个回答解决了您的问题吗?使用Python将Google文档公共电子表格下载为CSV文件 - Seanny123
2个回答

6
虽然requests库是Python中进行HTTP请求的黄金标准,但这种下载方式(虽然尚未被弃用)可能不会持续下去,具体指链接使用、管理Cookie和重定向等。不提倡使用链接的原因之一是它更不安全,通常这样的访问应该需要授权。取而代之,目前公认的导出Google Sheets为CSV文件的方式是通过使用Google Drive API

那么为什么要使用Drive API呢?这难道不是应该由Sheets API来处理吗?好吧,Sheet API主要处理与电子表格相关的功能,例如数据格式化、列调整大小、创建图表、单元格验证等等;而Drive API主要处理与文件相关的功能,例如导入/导出、复制、重命名等等。

以下是一个完整的命令行解决方案。(如果你不使用Python,你可以将其用作伪代码,并选择任何受Google APIs客户端库支持的语言。)对于代码片段,请假设当前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')

如果您的表格很大,您可能需要分块导出它 -- 参见此页面了解如何实现。如果您对Google APIs通常不熟悉,我有一段(有点过时但)用户友好的介绍视频可供您参考。(之后还有2个视频也可能有用。)

5
谷歌会用一系列设置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')

我将为您介绍如何使用纯Python实现,但现在我要说的是正确的方法™是使用最棒的requests库。 它有非常好的文档并且使这类任务变得令人愉快容易完成。

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

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

那一行代码表达了你的意图更清晰。它更容易编写,也更容易阅读。对于你自己和共享代码库的其他人来说,请使用requests,这样会更加方便。

感谢您的回复,非常感激! - elder elder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接