Загрузите общедоступную электронную таблицу в 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)
Другие вопросы по тегам