Загрузите общедоступную электронную таблицу в Google CSV с Python
Я могу скачать гугл документы CSV с 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. Что я делаю неправильно?
6 ответов
Просто используйте запросы, это намного лучше, чем использовать 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
Вы не храните куки.
Сначала позвольте мне сказать, что я полностью поддерживаю рекомендацию использовать самые превосходные requests
библиотека
Однако, если вам нужно сделать это в обычном Python 2, проблема заключается в том, что Google перенаправляет вас с помощью перенаправлений HTTP 302 и ожидает, что вы будете помнить файлы cookie, которые он устанавливает с каждым ответом. Когда он обнаруживает, что вы не храните куки, он перенаправляет вас на страницу входа.
По умолчанию, urllib2.urlopen
(или открывалка вернулась из build_opener
) будет следовать 302 перенаправлениям, но не будет хранить 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
если это вообще возможно, но если это невозможно, стандартная библиотека может выполнить свою работу.
Нет ничего проще, чем использовать
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)
requests
библиотека великолепна и является золотым стандартом для HTTP-запросов от Python, однако этот стиль загрузки, хотя и не устарел, вряд ли будет длиться долго, особенно в отношении стиля ссылки для скачивания. На самом деле, downloadUrl
поле в Google Drive API v2 уже устарело. В настоящее время приемлемым способом экспорта Google Sheets в формате CSV является использование (текущего) Google Drive API.
Так почему же Drive API? Разве это не должно быть что-то для Sheets API вместо этого? Итак, API Sheets предназначен для функциональности, ориентированной на электронные таблицы, т. Е. Для форматирования данных, изменения размера столбцов, создания диаграмм, проверки ячеек и т. Д., В то время как Drive API предназначен для функциональных возможностей, ориентированных на файлы, то есть для импорта / экспорта.
Ниже приведено полное решение cmd-line. (Если вы не используете Python, вы можете использовать его в качестве псевдокода и выбрать любой язык, поддерживаемый клиентскими библиотеками API Google.) Для фрагмента кода предположим, что самый последний лист называется inventory
(older files with that name are ignored) and DRIVE
is the API service endpoint:
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 видео после этого, может быть, тоже полезно.)
Я бы использовал запросы
import requests
r = requests.get('https://docs.google.com/spreadsheet/ccc?key=0ArM5yzzCw9IZdEdLWlpHT1FCcUpYQ2RjWmZYWmNwbXc&output=csv')
data = r.content
должны потребоваться запросы lib -> запросы на установку 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)