2010-07-20 64 views
24

Bạn có thể tạo ví dụ về cách tải xuống bảng tính Google Tài liệu bằng ID khóa và trang tính của mình (gid) không? Tôi không thể.Tải xuống bảng tính từ Google Documents bằng cách sử dụng Python

Tôi đã xóa các phiên bản 1, 2 và 3 của API. Tôi không có may mắn, tôi không thể tìm ra API nguồn cấp dữ liệu giống như ATOM, phương pháp riêng gdata.docs.service.DocsService._DownloadFile nói rằng tôi không được phép và tôi không muốn tự mình viết toàn bộ hệ thống xác thực đăng nhập của Google. Tôi chuẩn bị đâm vào mặt vì sự thất vọng.

Tôi có một vài bảng tính và tôi muốn để truy cập chúng như vậy:

username = '[email protected]' 
password = getpass.getpass() 

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

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

hãy giữ thể diện của tôi.


Cập nhật 1: Tôi đã thử những điều sau đây, nhưng không có sự kết hợp của Download() hoặc Export() dường như làm việc. (Documents cho DocsServicehere)

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 = '[email protected]' 
    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 
+1

Could [này] (http://stackoverflow.com/questions/2925985/syntaxerror-using-gdata-python-client-to-access-google-book-search-data-api/3013945#3013945) là vấn đề của bạn? – sje397

+0

Đã thử - cảm ơn! Dường như giúp tôi giải quyết vấn đề đăng nhập trong quá khứ. –

Trả lời

17

Trong trường hợp bất kỳ ai gặp phải vấn đề này cần sửa chữa nhanh, đây là another (currently) working solution không tái ly trên thư viện client 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) 
+1

tuyệt vời — một ví dụ tái sử dụng tốt đẹp! – MrColes

+0

Đây phải là giải pháp được chọn. Loại bỏ phụ thuộc gdata là một điểm cộng lớn và bạn thậm chí còn đóng gói nó theo cách mà nó có thể được sử dụng như cả ứng dụng bảng điều khiển và thư viện. Tôi đã thêm xử lý ngoại lệ xung quanh yêu cầu get_auth_token nhưng chỉ vì vậy tôi có thể xuất một thông báo có ý nghĩa khi gặp phải mật khẩu không chính xác. –

+0

Có lý do nào để lặp lại đối tượng 'csv_file' không? Tại sao không chỉ 'in csv_file.read()' - csv trong, csv ra! – Spacedman

0

Đây không phải là một câu trả lời hoàn chỉnh, nhưng Andreas Kahler viết lên một giải pháp CMS thú vị khi sử dụng Google Docs + Google App Engline + Python. Không có bất kỳ kinh nghiệm nào trong khu vực, tôi không thể thấy chính xác phần nào của mã có thể được sử dụng cho bạn, nhưng hãy kiểm tra nó. Tôi biết nó giao tiếp với một tài khoản Google Docs và chơi với các tập tin, vì vậy tôi có một cảm giác bạn sẽ nhận ra những gì đang xảy ra. Nó ít nhất sẽ chỉ cho bạn đi đúng hướng.

Google AppEngine + Google Docs + Some Python = Simple CMS

15

Bạn có thể thử bằng cách sử dụng phương pháp AuthSub mô tả trong phần Exporting Spreadsheets của tài liệu.

Nhận mã thông báo đăng nhập riêng cho dịch vụ bảng tính và thay thế mã đó cho lần xuất. Thêm này để mã get_spreadsheet làm việc cho tôi:

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 

Thông báo Tôi cũng sử dụng Export, như Download dường như cung cấp duy nhất tập tin PDF.

+6

OMGITWORKS! TRÀNG PHÁO TAY! NHIỆT LIỆT HOAN NGHÊNH! CERTIFIABLE SEAL CỦA KICKASSEDNESS! Cảm ơn ngài! Tôi ban cho ngươi tiền thưởng chín muồi của không ít hơn điểm tràn tràn FIFTY! Đưa họ đi, thưa bạn - Hãy đưa họ và CUỘC SỐNG TRỰC TIẾP NHƯ LÀ NÊN! –

+0

Nếu tôi có thể thêm tiền thưởng, tôi cũng sẽ làm như vậy. Cái này vừa cứu mạng tôi ở nơi làm việc. CẢM ƠN BẠN RẤT NHIỀU! – Mizmor

+2

Một [giải pháp tốt hơn] (http://stackoverflow.com/a/18296318/462302) hiện khả dụng vì câu trả lời này ban đầu được chấp nhận. – aculich

3

này không còn hoạt động như của gdata 2.0.1.4:

gd_client.SetClientLoginToken(spreadsheets_client.GetClientLoginToken()) 

Thay vào đó, bạn phải làm:

gd_client.SetClientLoginToken(gdata.gauth.ClientLoginToken(spreadsheets_client.GetClientLoginToken())) 
+0

bạn có thể đi theo cách khác không? đăng nhập bằng gd_client và sau đó chuyển mã thông báo cho khách hàng bảng tính? – michael

2

Các mã sau đây làm việc trong trường hợp của tôi (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 
24

Thư viện https://github.com/burnash/gspread là một cách đơn giản hơn mới hơn để tương tác với Google Spreadsheets, chứ không phải là câu trả lời cũ sang này mà đề nghị thư viện gdata đó là không chỉ quá ở mức độ thấp, nhưng cũng quá phức tạp.

Bạn cũng sẽ cần phải tạo ra và tải về (ở định dạng JSON) một phím Service Account: https://console.developers.google.com/apis/credentials/serviceaccountkey

Dưới đây là một ví dụ về cách sử dụng nó:

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()) 
+0

Chỉ cần kiểm tra. Có vẻ tốt và tôi sẽ đánh dấu nó là mặc định. Tuyệt vời! –

+2

Chỉ cần sử dụng này cũng có, công cụ tuyệt vời! ps - bạn có thể thay đổi phương thức để sử dụng tên doc thay vì phím đẹp. –

+1

Và điều này chỉ tải tất cả các trang tính. Có thể tải trang tính theo gid, không phải chỉ mục hoặc tên không? – d12frosted

0

Gspread thực sự là một bước tiến lớn so GoogleCL và Gdata (cả hai đều đã sử dụng và may mắn được loại bỏ để ủng hộ Gspread). Tôi nghĩ rằng mã này thậm chí còn nhanh hơn câu trả lời trước đó để có được nội dung của trang tính:

username = '[email protected]' 
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) 
1

Tôi đã đơn giản hóa @ Cameron hơn nữa, bằng cách loại bỏ định hướng đối tượng không cần thiết. Điều này làm cho mã nhỏ hơn và dễ hiểu hơn. Tôi cũng đã chỉnh sửa url, có thể hoạt động tốt hơn.

#!/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

Giải pháp này đã lỗi thời và sẽ không hoạt động, như tất cả các câu trả lời ở đây bạn cần sử dụng oauth2.0 – Richard

3

(tháng 7 năm 2016) rephrasing với thuật ngữ hiện nay: "Làm thế nào để tải về một tấm Google ở ​​định dạng CSV từ Google sử dụng Python?". (Google Documents hiện chỉ đề cập đến trình soạn thảo văn bản/trình soạn thảo văn bản dựa trên đám mây không cung cấp quyền truy cập vào bảng tính Google Trang tính.)

Đầu tiên, tất cả các câu trả lời khác là khá lỗi thời hoặc sẽ là do chúng sử dụng cũ GData (" Google Data") Protocol, ClientLogin, hoặc AuthSub, tất cả đều đã bị phản đối. Điều này cũng đúng đối với tất cả các mã hoặc thư viện mà sử dụng v3 Google Sheets API trở lên.

truy cập API hiện đại của Google xuất hiện sử dụng các phím API hoặc Ủy quyền OAuth2, chủ yếu với Google APIs Client Libraries, bao gồm the one for Python. (Và không, bạn không phải xây dựng toàn bộ hệ thống xác thực chỉ để truy cập API ... xem bài đăng blog bên dưới.)

Để thực hiện tác vụ được yêu cầu trong/bởi OP, bạn sẽ sử dụng Google Drive API, có thể truy vấn Trang tính cụ thể để tải xuống và sau đó thực hiện (các) xuất thực tế. Vì đây có thể là một hoạt động phổ biến, tôi đã viết một đoạn mã blogpost chia sẻ một đoạn mã thực hiện điều này cho bạn. Nếu bạn muốn theo đuổi điều này nhiều hơn, tôi có một cặp khác là posts cùng với video nêu rõ cách tải tệp lên và tải xuống tệp từ Google Drive.

Lưu ý rằng cũng có một số mới là Google Sheets API v4, nhưng chủ yếu cho các hoạt động định hướng bảng tính, ví dụ: chèn dữ liệu, đọc hàng bảng tính, định dạng ô, tạo biểu đồ, thêm bảng tổng hợp, v.v. xuất ra nơi API Drive là đúng để sử dụng.

Để xem ví dụ về việc xuất Google Trang tính dưới dạng CSV từ Drive, hãy xem this blog post Tôi đã viết; để tìm hiểu thêm về cách sử dụng Google Trang tính với Python, hãy xem this answer I wrote cho một câu hỏi tương tự.

0

(Dec 16) Hãy thử một thư viện khác tôi đã viết: pygsheets. Nó tương tự như gspread, nhưng sử dụng google api v4. Nó có phương thức export để xuất bảng tính.

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) 
Các vấn đề liên quan