7

公開されたGoogleスプレッドシートドキュメントに由来するcsvファイルを保存する簡単な方法を探していますか?公開されているため、直接リンクからアクセスできます(以下の例では意図的に変更されています)。

リンクを起動するとすぐに、すべてのブラウザでcsvファイルを保存するように求められます。

ない:

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)

、 または:

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

HTMLコンテンツ以外のものを印刷します。

(この他の投稿を読んだ後、2番目のバージョンを試しました:Pythonでgoogle docs公開スプレッドシートをcsvにダウンロードしてください。)

私が間違っていることについて何か考えはありますか?私は自分のGoogleアカウントからログアウトしていますが、それが何か価値がある場合は、これは私が試したどのブラウザからでも機能します。私が理解している限り、Google DocsAPIはまだPython3に移植されておらず、個人的な使用のための私の小さなプロジェクトの「おもちゃ」の大きさを考えると、最初からそれを使用することはあまり意味がありません。私はそれを回避することができます。

2回目の試行では、スクリプトからのリクエスト(b / cは識別情報が存在しない)が無視される可能性があると考えていたため、「User-Agent」を残しましたが、違いはありませんでした。

4

2 に答える 2

6

ライブラリはrequestsPythonからのHTTPリクエストのゴールドスタンダードですが、このスタイルのダウンロードは(まだ非推奨ではありませんが)長続きしない可能性があります。具体的には、リンクの使用、Cookieとリダイレクトの管理などですリンクを優先するのは、安全性が低く、通常、そのようなアクセスには承認が必要なことです。代わりに、現在受け入れられているGoogleスプレッドシートをCSVとしてエクスポートする方法は、GoogleドライブAPIを使用することです。

では、なぜDrive APIなのか?代わりに、これはSheets APIのためのものではないでしょうか?Sheets APIは、データの書式設定、列のサイズ変更、グラフの作成、セルの検証などのスプレッドシート指向の機能用ですが、Drive APIは、インポート/エクスポート、コピー、名前変更などのファイル指向の機能用です。等

以下は完全なコマンドラインソリューションです。(Pythonを使用しない場合は、疑似コードとして使用し、Google APIクライアントライブラリでサポートされている任意の言語を選択できます。)コードスニペットでは、名前が付けられた最新のシートinventory(その名前の古いファイルは無視されます)をDRIVE想定します。 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')

シートが大きい場合は、チャンクでエクスポートする必要がある場合があります。その方法については、このページを参照ください。あなたが一般的にGoogleAPIに不慣れであるなら、私はあなたのために(やや時代遅れですが)ユーザーフレンドリーな紹介ビデオを持っています。(その後、2つのビデオがありますが、これも役立つかもしれません。)

于 2017-03-09T05:14:32.340 に答える
5

Googleは、一連のCookie設定302リダイレクトで最初のリクエストに応答します。リクエストの合間にCookieを保存して再送信しないと、ログインページにリダイレクトされます。

したがって、問題はUser-Agentヘッダーにあるのではなく、デフォルトでurllib.request.urlopenはCookieを保存しないという事実ですが、HTTP302リダイレクトに従います。

次のコードは、次の場所で指定された場所にある公開スプレッドシートで問題なく機能します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')

バニラPythonでそれを行う方法を示したので、これを実行するためのRightWay™は、最も優れたリクエストライブラリを使用することであると言います。それは非常によく文書化されており、これらの種類のタスクを完了するのが非常に楽しいものになります。

たとえばcsv_content、ライブラリを使用して上記と同じものを取得するには、次のrequestsように簡単です。

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

その一行はあなたの意図をより明確に表現しています。書きやすく、読みやすいです。あなた自身(そしてあなたのコードベースを共有する他の誰か)に賛成して、ただ使用してくださいrequests

于 2013-04-10T19:49:10.323 に答える