Загрузите общедоступную таблицу google docs в csv с помощью python

Я могу загрузить файл CSV из Документов Google с помощью wget:

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

Но я не могу скачать тот же CSV с Python:

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. Что я делаю неправильно?

Ответ 1

Просто используйте запросы, это намного лучше, чем использовать 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

Ответ 2

Вы не храните файлы cookie.

Прежде всего позвольте мне сказать, что я полностью одобряю рекомендацию использовать самую превосходную requests библиотеку.

Однако, если вам нужно сделать это в ванильном Python 2, проблема кроется в том, что Google подталкивает вас через HTTP 302 перенаправления и ожидает, что вы будете помнить файлы cookie, которые он устанавливает с каждым ответом. Когда он обнаруживает, что вы не храните файлы cookie, он перенаправляет вас на страницу входа.

По умолчанию urllib2.urlopen (или открыватель, возвращаемый из build_opener), будет следовать 302 перенаправлениям, но он не будет хранить файлы cookie HTTP. Вы должны научить своего новичка, как это сделать. Например:

>>> 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, если это вообще возможно, но если это невозможно, стандартная библиотека может выполнить задание.

Ответ 3

Библиотека requests отличная и золотой стандарт для HTTP-запросов от Python, однако этот стиль загрузки, хотя и не устарел, вряд ли сохранится, в частности, ссылаясь на стиль загрузки. На самом деле поле downloadUrl в Google Диске API v2 уже устарели. В настоящее время принятый способ экспортировать Google Таблицы в формате CSV - это использовать (текущий) API Google Диска.

Итак, почему API-интерфейс Drive? Разве это не должно быть чем-то для Листы API вместо этого? Ну, API-интерфейс "Таблицы" предназначен для таблиц -ориентированной функциональности, то есть форматирования данных, изменения размера столбца, создания диаграмм, проверки ячейки и т.д., В то время как API-интерфейс Drive для файла - ориентированная функциональность, то есть импорт/экспорт.

Ниже приведено полное решение cmd-line. (Если вы не используете Python, вы можете использовать его как псевдокод и выбрать любой язык, поддерживаемый Клиентскими библиотеками API Google.) фрагмент кода, предположим, что самый последний лист с именем 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')

Если ваш лист большой, вам, возможно, придется экспортировать его в куски - см. эту страницу о том, как это сделать. Если вы вообще новичок в API Google, у меня есть (несколько устаревший, но) удобный интро видео для вас. (После этого есть 2 видео, которые могут быть полезны.)

Ответ 4

я использовал бы запросы

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