13

我可以从 Google Docs 下载 CSV 文件wget

wget --no-check-certificate --output-document=locations.csv 'https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv'

但我不能用 Python 下载相同的 csv:

import urllib2

request = urllib2.Request('https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv')
request.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')
opener = urllib2.build_opener()
data = opener.open(request).read()
print(data)

结果是谷歌登录页面。我究竟做错了什么?

4

6 回答 6

29

只需使用requests,它比使用 urllib 更好:

import requests
response = requests.get('https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv')
assert response.status_code == 200, 'Wrong status code'
print(response.content)

你可以安装它

pip install requests
于 2012-10-11T15:01:08.313 回答
12

您没有存储 cookie。

首先让我说我完全赞同使用最优秀requests的建议。

但是,如果您需要在原版 Python 2 中执行此操作,问题在于 Google 通过 HTTP 302 重定向来回弹您,并且它希望您记住它为每个响应设置的 cookie。当它检测到您没有存储 cookie 时,会将您重定向到登录页面。

默认情况下,urllib2.urlopen(或从 返回的开启程序build_opener)将遵循 302 重定向,但它不会存储 HTTP cookie。你必须教你的开瓶器如何做到这一点。像这样:

>>> from cookielib import CookieJar
>>> from urllib2 import build_opener, HTTPCookieProcessor
>>> opener = build_opener(HTTPCookieProcessor(CookieJar()))
>>> resp = opener.open('https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv')
>>> data = resp.read()

同样,尽可能使用requests,但如果不可能,标准库可以完成工作。

于 2013-04-10T20:10:17.320 回答
2

requests库非常棒,是来自 Python 的 HTTP 请求的黄金标准,但是这种下载方式虽然还没有被弃用,但不太可能持续下去,特别是指下载链接样式。事实上,Google Drive API v2中的downloadUrl字段已经被弃用了。目前接受的将 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 1st matching 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-09T04:47:29.633 回答
2

没有比使用更简单的了Pandas

def build_sheet_url(doc_id, sheet_id):
    return f'https://docs.google.com/spreadsheets/d/{doc_id}/export?format=csv&gid={sheet_id}'

def write_df_to_local(df, file_path):
    df.to_csv(file_path)

doc_id = 'DOC_ID'
sheet_id = 'SHEET_ID'
sheet_url = build_sheet_url(doc_id, sheet_id)
df = pd.read_csv(sheet_url)
file_path = 'FILE_PATH'
write_df_to_local(df, file_path)
于 2021-08-07T16:18:26.117 回答
0

我会使用请求

import requests
r = requests.get('https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv')
data = r.content
于 2012-10-11T15:00:03.363 回答
0

必须需要请求库-> pip 安装请求

from urllib.parse import urlparse
import requests

link = "https://docs.google.com/spreadsheets/d/11D0KAvm_ERXZ3XMgft5DM19IREaNvGargPlvW8e2DXg/edit#gid=0"
domain = urlparse(link).netloc
segments = link.rpartition('/')
link = segments[0] + "/export?format=csv"
file = requests.get(link)
if file.status_code == 200:
    fileContent = file.content.decode('utf-8')
    print(fileContent)
于 2021-04-15T04:17:30.110 回答