Как сохранить файл Google Sheets в формате CSV из Python 3 (или 2)?
Я ищу простой способ сохранить csv-файл, полученный из опубликованного документа Google Sheets? Поскольку он опубликован, он доступен по прямой ссылке (специально измененной в приведенном ниже примере).
Все мои браузеры будут предлагать мне сохранить файл 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-контента.
(попробовал 2-ю версию после прочтения этого другого поста: Скачать google docs публичная электронная таблица в csv с python .)
Есть идеи, что я делаю не так? Я вышел из своего аккаунта Google, если это что-то значит, но это работает с любого браузера, который я пробовал. Насколько я понял, API Google Docs еще не портирован на Python 3, и, учитывая "игрушечный" масштаб моего маленького проекта для личного использования, было бы даже не слишком разумно использовать его с самого начала, если бы я мог обойти его.
Во 2-й попытке я оставил "User-Agent", так как я я думал, что, возможно, запросы, считающиеся исходящими из скриптов (b/c отсутствует идентификационная информация), могут быть проигнорированы, но это не имело значения.
2 ответа:
Google отвечает на первоначальный запрос серией переадресаций 302 файлов cookie. Если вы не сохраняете и не пересылаете файлы 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, я теперь скажу, что правильный способ™ сделать это-использовать самый-превосходный библиотека запросов. Это так очень хорошо документировано и делает эти виды задач невероятно приятными для выполнения.
Например, получить то же самое
csv_content
, что и выше, используя библиотекуrequests
, так же просто, как:Эта единственная строка более ясно выражает ваше намерение. Это легче писать и легче читать. Сделайте себе - и всем, кто разделяет вашу кодовую базу-одолжение и просто используйте>>> import requests >>> csv_content = requests.get(DOC_URL).text
requests
.
Хотя библиотека
requests
является золотым стандартом для HTTP-запросов от Python, Этот стиль загрузки (хотя он еще не устарел), скорее всего, не будет длиться, особенно в отношении использования ссылок, управления файлами cookie и перенаправлениями и т. д. Одна из причин, по которой Не предпочитают ссылки, заключается в том, что это менее безопасно и обычно такой доступ должен требовать авторизации. Вместо этого, в настоящее время общепринятым способом экспорта Google Sheets в формате CSV является Использование диска Google API .Так почему же Drive API? Разве это не должно быть что-то для API листов вместо этого? Ну, API листов предназначен дляэлектронной таблицы -ориентированной функциональности, то есть форматирования данных, изменения размера столбцов, создания диаграмм, проверки ячеек и т. д., в то время как API диска предназначен для file-ориентированной функциональности, т. е. импорта/экспорта, копирования, переименования и т. д.
Ниже приводитсяполное решение командной строки . (Если вы не используете Python, вы можете использовать его как псевдокод и выбрать любой язык, поддерживаемый API-интерфейсов клиентских библиотек.) Для фрагмента кода предположим, что самый текущий лист с именем
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 видео после этого, которые, возможно, тоже полезны.)