【问题标题】:Download google docs public spreadsheet to csv with python使用 python 将谷歌文档公共电子表格下载到 csv
【发布时间】:2012-10-11 14:48:20
【问题描述】:

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

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)

结果是 Google 登录页面。我做错了什么?

【问题讨论】:

    标签: python google-sheets


    【解决方案1】:

    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
    

    【讨论】:

    • nitpick:您应该使用response.raise_for_status() 而不是断言response.status_code == 200,原因很简单,当使用优化标志运行python 时,assert 语句会被删除。
    • 这只是为了解释,如果你使用python优化部署代码,所有的断言都会被剥离。
    • 嘿@JaysonReis,是否可以选择您需要的工作表。而且,当您只指定 `&output=csv' 时,您是只得到其中一个还是全部?
    • 对我不起作用。我不得不使用'https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc/export?format=csv'
    • 这些 URL 多年来可能发生了变化,如果您检查 google doc 的 API 并可能使用一些已经实现这些功能的库会更好。
    【解决方案2】:

    您没有存储 cookie。

    首先让我说我完全赞同使用most-excellent requests library 的建议。

    但是,如果您需要在原版 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,但如果不可能,标准库可以完成这项工作。

    【讨论】:

    • +1 用于提供普通的 python 2 解决方案。并非每个人都必须有能力或授权来安装新库。
    【解决方案3】:

    没有比使用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)
    

    【讨论】:

      【解决方案4】:

      requests 库非常棒,是来自 Python 的 HTTP 请求的黄金标准,但是这种下载方式虽然还没有被弃用,但不太可能持续下去,特别是指下载链接样式。事实上,Google Drive API v2 中的downloadUrl 字段就是already deprecated。目前接受的将 Google 表格导出为 CSV 的方式是使用(当前)Google Drive API

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

      下面是complete cmd-line solution。 (如果您不使用 Python,则可以将其用作伪代码并选择 Google APIs Client Libraries 支持的任何语言。)对于代码 sn-p,假设最新的工作表名为 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')
      

      如果您的工作表很大,您可能必须将其分块导出——请参阅this page 了解如何执行。如果您通常是 Google API 的新手,我有一个(有些过时但)用户友好的 intro video 供您使用。 (之后还有 2 个视频也可能有用。)

      【讨论】:

        【解决方案5】:

        我会使用请求

        import requests
        r = requests.get('https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv')
        data = r.content
        

        【讨论】:

          【解决方案6】:

          必须需要请求库 --> 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)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-07-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-30
            • 2023-03-13
            • 1970-01-01
            • 2011-08-28
            相关资源
            最近更新 更多