Загрузите электронную таблицу из Документов Google, используя Python - PullRequest
31 голосов
/ 20 июля 2010

Можете ли вы привести пример Python для загрузки электронной таблицы Документов Google с указанием ее ключа и идентификатора таблицы (gid)? Я не могу.

Я изучил версии 1, 2 и 3 API. Мне не повезло, я не могу выяснить их API-интерфейс, подобный ATOM-подобным каналам, приватный метод gdata.docs.service.DocsService._DownloadFile говорит, что я не авторизован, и я не хочу сам писать всю систему аутентификации в Google Login. Я собираюсь нанести удар себе в лицо из-за разочарования.

У меня есть несколько таблиц, и я хочу получить к ним доступ следующим образом:

username = 'mygooglelogin@gmail.com'
password = getpass.getpass()

def get_spreadsheet(key, gid=0):
    ... (help!) ...

for row in get_spreadsheet('5a3c7f7dcee4b4f'):
    cell1, cell2, cell3 = row
    ...

Пожалуйста, спасите мое лицо.


Обновление 1: Я пробовал следующее, но комбинация Download() или Export(), похоже, не работает. (Документы для DocsService здесь )

import gdata.docs.service
import getpass
import os
import tempfile
import csv

def get_csv(file_path):
  return csv.reader(file(file_path).readlines())

def get_spreadsheet(key, gid=0):
  gd_client = gdata.docs.service.DocsService()
  gd_client.email = 'xxxxxxxxx@gmail.com'
  gd_client.password = getpass.getpass()
  gd_client.ssl = False
  gd_client.source = "My Fancy Spreadsheet Downloader"
  gd_client.ProgrammaticLogin()

  file_path = tempfile.mktemp(suffix='.csv')
  uri = 'http://docs.google.com/feeds/documents/private/full/%s' % key
  try:
    entry = gd_client.GetDocumentListEntry(uri)

    # XXXX - The following dies with RequestError "Unauthorized"
    gd_client.Download(entry, file_path)

    return get_csv(file_path)
  finally:
    try:
      os.remove(file_path)
    except OSError:
      pass

Ответы [ 11 ]

30 голосов
/ 18 августа 2013

Библиотека https://github.com/burnash/gspread - это более новый и простой способ взаимодействия с таблицами Google, нежели старые ответы на этот вопрос, в которых предлагается библиотека gdata, которая не только слишком низкоуровневая, но и чрезмерно излишняя.-complicated.

Вам также потребуется создать и загрузить (в формате JSON) ключ учетной записи службы: https://console.developers.google.com/apis/credentials/serviceaccountkey

Вот пример его использования:

import csv
import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)

docid = "0zjVQXjJixf-SdGpLKnJtcmQhNjVUTk1hNTRpc0x5b9c"

client = gspread.authorize(credentials)
spreadsheet = client.open_by_key(docid)
for i, worksheet in enumerate(spreadsheet.worksheets()):
    filename = docid + '-worksheet' + str(i) + '.csv'
    with open(filename, 'wb') as f:
        writer = csv.writer(f)
        writer.writerows(worksheet.get_all_values())
20 голосов
/ 25 января 2012

Если кто-то сталкивается с этим в поисках быстрого исправления, вот другое (в настоящее время) работающее решение , которое не зависит от клиентской библиотеки gdata:

#!/usr/bin/python

import re, urllib, urllib2

class Spreadsheet(object):
    def __init__(self, key):
        super(Spreadsheet, self).__init__()
        self.key = key

class Client(object):
    def __init__(self, email, password):
        super(Client, self).__init__()
        self.email = email
        self.password = password

    def _get_auth_token(self, email, password, source, service):
        url = "https://www.google.com/accounts/ClientLogin"
        params = {
            "Email": email, "Passwd": password,
            "service": service,
            "accountType": "HOSTED_OR_GOOGLE",
            "source": source
        }
        req = urllib2.Request(url, urllib.urlencode(params))
        return re.findall(r"Auth=(.*)", urllib2.urlopen(req).read())[0]

    def get_auth_token(self):
        source = type(self).__name__
        return self._get_auth_token(self.email, self.password, source, service="wise")

    def download(self, spreadsheet, gid=0, format="csv"):
        url_format = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=%s&exportFormat=%s&gid=%i"
        headers = {
            "Authorization": "GoogleLogin auth=" + self.get_auth_token(),
            "GData-Version": "3.0"
        }
        req = urllib2.Request(url_format % (spreadsheet.key, format, gid), headers=headers)
        return urllib2.urlopen(req)

if __name__ == "__main__":
    import getpass
    import csv

    email = "" # (your email here)
    password = getpass.getpass()
    spreadsheet_id = "" # (spreadsheet id here)

    # Create client and spreadsheet objects
    gs = Client(email, password)
    ss = Spreadsheet(spreadsheet_id)

    # Request a file-like object containing the spreadsheet's contents
    csv_file = gs.download(ss)

    # Parse as CSV and print the rows
    for row in csv.reader(csv_file):
        print ", ".join(row)
17 голосов
/ 31 июля 2010

Вы можете попробовать использовать метод AuthSub, описанный в разделе Экспорт таблиц документации.

Получить отдельный маркер входа для службы электронных таблиц и заменить его для экспорта.Добавление этого в код get_spreadsheet сработало для меня:

import gdata.spreadsheet.service

def get_spreadsheet(key, gid=0):
    # ...
    spreadsheets_client = gdata.spreadsheet.service.SpreadsheetsService()
    spreadsheets_client.email = gd_client.email
    spreadsheets_client.password = gd_client.password
    spreadsheets_client.source = "My Fancy Spreadsheet Downloader"
    spreadsheets_client.ProgrammaticLogin()

    # ...
    entry = gd_client.GetDocumentListEntry(uri)
    docs_auth_token = gd_client.GetClientLoginToken()
    gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken())
    gd_client.Export(entry, file_path)
    gd_client.SetClientLoginToken(docs_auth_token) # reset the DocList auth token

Обратите внимание, что я также использовал Export, так как Download, похоже, дает только файлы PDF.

3 голосов
/ 12 июля 2016

(июль 2016 г.) Перефразирование с использованием текущей терминологии: " Как загрузить лист Google в формате CSV из Google Диск с использованием Python ?". (Документы Google теперь относятся только к облачному текстовому процессору / текстовому редактору, который не предоставляет доступ к таблицам Google Sheets.)

Во-первых, все остальные ответы в значительной степени устарели или будут устаревшими, поскольку они используют старый протокол GData (" Google Data") , ClientLogin или AuthSub , все из которых устарели. То же самое относится ко всему коду или библиотекам, использующим API Google Sheets v3 или более поздней версии.

Современный доступ к API Google осуществляется с использованием ключей API (общедоступные данные) или авторизации OAuth2 (авторизованные данные), в первую очередь с клиентскими библиотеками Google APIs , включая для Python . (И нет, вам не нужно создавать целую систему аутентификации только для доступа к API ... см. Пост в блоге ниже.)

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

Обратите внимание, что есть также более новый Google Sheets API v4 , но он в основном предназначен для операций с электронными таблицами , т. Е. Вставки данных, чтения строк электронной таблицы, форматирования ячеек, создания диаграмм добавление сводных таблиц и т. д., а не запрос на основе файла , например, экспорт, когда Drive API является правильным для использования.

Чтобы увидеть пример экспорта Google Листа в виде CSV с диска, ознакомьтесь с этим сообщением в блоге Я написал; чтобы узнать больше об использовании Google Sheets с Python, см. этот ответ, который я написал для аналогичного вопроса.

Если вы совершенно не знакомы с API Google, вам нужно сделать еще один шаг назад и сначала просмотреть эти видео:

3 голосов
/ 24 марта 2011

Это больше не работает с gdata 2.0.1.4:

gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken())

Вместо этого вы должны сделать:

gd_client.SetClientLoginToken(gdata.gauth.ClientLoginToken(spreadsheets_client.GetClientLoginToken()))
2 голосов
/ 08 мая 2011

Следующий код работает в моем случае (Ubuntu 10.4, python 2.6.5 gdata 2.0.14)

import gdata.docs.service
import gdata.spreadsheet.service
gd_client = gdata.docs.service.DocsService()
gd_client.ClientLogin(email,password)
spreadsheets_client = gdata.spreadsheet.service.SpreadsheetsService()
spreadsheets_client.ClientLogin(email,password)
#...
file_path = file_path.strip()+".xls"
docs_token = gd_client.auth_token
gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken())
gd_client.Export(entry, file_path)  
gd_client.auth_token = docs_token
1 голос
/ 12 октября 2014

Я упростил ответ Кэмерон еще дальше, убрав ненужную ориентацию объекта. Это делает код меньше и легче для понимания. Я также отредактировал URL, который мог бы работать лучше.

#!/usr/bin/python
import re, urllib, urllib2

def get_auth_token(email, password):
    url = "https://www.google.com/accounts/ClientLogin"
    params = {
        "Email": email, "Passwd": password,
        "service": 'wise',
        "accountType": "HOSTED_OR_GOOGLE",
        "source": 'Client'
    }
    req = urllib2.Request(url, urllib.urlencode(params))
    return re.findall(r"Auth=(.*)", urllib2.urlopen(req).read())[0]

def download(spreadsheet, worksheet, email, password, format="csv"):
    url_format = 'https://docs.google.com/spreadsheets/d/%s/export?exportFormat=%s#gid=%s'

    headers = {
        "Authorization": "GoogleLogin auth=" + get_auth_token(email, password),
        "GData-Version": "3.0"
    }
    req = urllib2.Request(url_format % (spreadsheet, format, worksheet), headers=headers)
    return urllib2.urlopen(req)


if __name__ == "__main__":
    import getpass
    import csv

    spreadsheet_id = ""             # (spreadsheet id here)
    worksheet_id = ''               # (gid here)
    email = ""                      # (your email here)
    password = getpass.getpass()

    # Request a file-like object containing the spreadsheet's contents
    csv_file = download(spreadsheet_id, worksheet_id, email, password)

    # Parse as CSV and print the rows
    for row in csv.reader(csv_file):
        print ", ".join(row)
0 голосов
/ 05 марта 2019

(март 2019, Python 3) Мои данные обычно не чувствительны, и я обычно использую табличный формат, похожий на CSV.

В таком случае можно просто publish to the web лист и затем использовать его в качестве файла CSV на сервере.

(Один публикует его, используя File -> Publish to the web ... -> Sheet 1 -> Comma separated values (.csv) -> Publish).

import csv
import io
import requests

url = "https://docs.google.com/spreadsheets/d/e/<GOOGLE_ID>/pub?gid=0&single=true&output=csv"  # you can get the whole link in the 'Publish to the web' dialog
r = requests.get(url)
r.encoding = 'utf-8'
csvio = io.StringIO(r.text, newline="")
data = []
for row in csv.DictReader(csvio):
    data.append(row)
0 голосов
/ 11 декабря 2016

(16 декабря) Попробуйте другую библиотеку, которую я написал: pygsheets . Это похоже на gspread, но использует google api v4. У него есть export метод для экспорта электронных таблиц.

import pygsheets

gc = pygsheets.authorize()

# Open spreadsheet and then workseet
sh = gc.open('my new ssheet')
wks = sh.sheet1

#export as csv
wks.export(pygsheets.ExportType.CSV)
0 голосов
/ 14 сентября 2014

Gspread действительно является большим улучшением по сравнению с GoogleCL и Gdata (оба из которых я использовал, и, к счастью, постепенно отказался от Grald). Я думаю, что этот код еще быстрее, чем предыдущий ответ, чтобы получить содержимое листа:

username = 'sdfsdfsds@gmail.com'
password = 'sdfsdfsadfsdw'
sheetname = "Sheety Sheet"

client = gspread.login(username, password)
spreadsheet = client.open(sheetname)

worksheet = spreadsheet.sheet1
contents = []
for rows in worksheet.get_all_values():
    contents.append(rows)
...