5

Tôi đang tìm một cách đơn giản để lưu tệp csv có nguồn gốc từ tài liệu Google Trang tính đã xuất bản? Kể từ khi nó được xuất bản, nó có thể truy cập thông qua một liên kết trực tiếp (sửa đổi về mục đích trong ví dụ dưới đây).Làm cách nào để lưu tệp Google Trang tính dưới dạng CSV từ Python 3 (hoặc 2)?

Tất cả trình duyệt của tôi sẽ nhắc tôi lưu tệp csv ngay khi tôi khởi chạy liên kết.

Cả:

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) 

, cũng không phải:

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')) 

in bất cứ điều gì nhưng nội dung html.

(thử phiên bản thứ 2 sau khi đọc bài này khác: Download google docs public spreadsheet to csv with python.)

Bất kỳ ý tưởng về những gì tôi đang làm sai? Tôi đã đăng xuất khỏi tài khoản Google của mình, nếu điều đó có giá trị với bất kỳ điều gì, nhưng điều này hoạt động từ bất kỳ trình duyệt nào mà tôi đã thử. Theo như tôi đã hiểu, API Google Documents chưa được chuyển sang Python 3 và cho độ lớn "đồ chơi" của dự án nhỏ của tôi cho mục đích sử dụng cá nhân, nó thậm chí sẽ không tạo ra quá nhiều ý nghĩa để sử dụng nó từ khi bắt đầu, nếu Tôi có thể phá vỡ nó.

Trong lần thử thứ hai, tôi đã bỏ 'Tác nhân người dùng', vì tôi nghĩ rằng có thể các yêu cầu được cho là đến từ tập lệnh (b/c không có thông tin nhận dạng) có thể bị bỏ qua. một sự khác biệt.

Trả lời

4

Google trả lời yêu cầu ban đầu bằng một loạt chuyển hướng thiết lập cookie 302. Nếu bạn không lưu trữ và gửi lại cookie giữa các yêu cầu, nó sẽ chuyển hướng bạn đến trang đăng nhập.

Vì vậy, vấn đề không phải với tiêu đề Tác nhân người dùng, thực tế là theo mặc định, urllib.request.urlopen không lưu trữ cookie, nhưng nó sẽ thực hiện theo các chuyển hướng HTTP 302.

Đoạn mã dưới đây chỉ hoạt động tốt trên một bảng tính công cộng có sẵn tại địa điểm theo quy định của 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') 

Sau khi cho các bạn làm thế nào để làm điều đó trong vani python, bây giờ tôi sẽ nói rằng Right Way ™ để giải quyết vấn đề này là sử dụng requests library tuyệt vời nhất. Đó là extremely well documented và làm cho những công việc này trở nên vô cùng dễ chịu để hoàn thành.

Ví dụ, để có được cùng csv_content như trên bằng cách sử dụng thư viện requests cũng đơn giản như:

>>> import requests 
>>> csv_content = requests.get(DOC_URL).text 

Đó dòng duy nhất bày tỏ ý định của bạn rõ ràng hơn. Viết và đọc dễ dàng hơn. Tự làm - và bất kỳ ai khác chia sẻ mã nguồn của bạn - ưu tiên và chỉ sử dụng requests.

+0

Cảm ơn bạn đã phản hồi, thực sự đánh giá cao nó! –

2

Trong khi thư viện requests là tiêu chuẩn vàng cho các yêu cầu HTTP từ Python, kiểu tải xuống này (mặc dù không được dùng nữa) không thể kéo dài, cụ thể là việc sử dụng liên kết, quản lý cookie & chuyển hướng, v.v.Một trong những lý do cho các liên kết ưu tiên không phải là là nó kém an toàn hơn và thường quyền truy cập như vậy sẽ yêu cầu ủy quyền. Thay vào đó, cách xuất hiện được chấp nhận của Google Trang tính dưới dạng CSV là bằng cách sử dụng số Google Drive API.

Vậy tại sao API Drive? Có phải đây không phải là thứ gì đó cho số Sheets API thay thế không? Vâng, API trang tính dành cho bảng tính chức năng định hướng, tức là định dạng dữ liệu, đổi kích thước cột, tạo biểu đồ, xác thực ô, v.v. trong khi API Drive dành cho tệp chức năng định hướng, tức là nhập/xuất, sao chép, đổi tên, v.v.

Dưới đây là complete cmd-line solution. (Nếu bạn không làm Python, bạn có thể sử dụng nó như mã giả và chọn bất kỳ ngôn ngữ nào được hỗ trợ bởi Google APIs Client Libraries.) Đối với đoạn mã, giả sử Trang tính mới nhất có tên inventory (các tệp cũ hơn có tên đó bị bỏ qua) và DRIVE là điểm cuối dịch vụ 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') 

Nếu tấm của bạn lớn, bạn có thể phải xuất nó trong khối - xem this page về cách làm rằng. Nếu bạn thường mới sử dụng API Google, tôi có một số (01) ngày thân thiện với người dùng) intro video cho bạn. (Có 2 video sau đó cũng có thể hữu ích.)

Các vấn đề liên quan