7

我正在寻找一种简单的方法来保存源自已发布的 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 不存在标识信息)可能会被忽略,但这并没有什么不同。

4

2 回答 2

6

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

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

下面是一个完整的命令行解决方案。(如果您不使用 Python,则可以将其用作伪代码并选择Google APIs Client Libraries支持的任何语言。)对于代码片段,假设最新的工作表命名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 API 的新手,我为您准备了一个(有些过时但)用户友好的介绍视频。(之后有 2 个视频也可能有用。)

于 2017-03-09T05:14:32.340 回答
5

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 库。它有很好的文档记录,使这些任务完成起来非常愉快。

例如,csv_content使用requests库获得与上面相同的内容非常简单:

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

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

于 2013-04-10T19:49:10.323 回答