[Python] Access google drive with google api using python

自從來到上海工作以後,在Mac上用了Shadowsocks和Proxifier連我的ssr節點,想要備份文件檔案動畫
試過了Dropbox、Google Drive、Google Drive File Stream和OneDrive,
至於iCloud只有50GB就放棄用來放資料乖乖備份手機就好。

可是在這些雲端硬碟之中只有dropbox可以穩定的上傳大小檔案,dropbox之外的同步小檔案沒有問題,
只要上傳超過20MB的,進度百分比跑到一定數字就會卡住,然後開始出現連線錯誤...所以想要來自己寫!!
這樣至少可以看到詳細錯誤訊息...(希望)

前幾天在windows筆電上試了用.NET呼叫google drive api上傳成功後,接下來想在Mac上用python試。

事前準備:安裝pythone2.6以上版本、pip、Google Client Library
Google Developers Python Quickstart

再把google提供的python範例抄下來執行看看。

事情果然沒有那麼順利,出現了一大串看不懂的錯誤...
Traceback (most recent call last):
  File "quickstart.py", line 22, in <module>
    creds = tools.run_flow(flow, store)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/tools.py", line 243, in run_flow
    credential = flow.step2_exchange(code, http=http)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/client.py", line 2054, in step2_exchange
    http, self.token_uri, method='POST', body=body, headers=headers)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/transport.py", line 282, in request
    connection_type=connection_type)
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1514, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1264, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1187, in _conn_request
    conn.connect()
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1050, in connect
    raise socket_err
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1011, in connect
    sock.connect((self.host, self.port))
OSError: [Errno 65] No route to host

中間一大串其實沒有看懂,應該就是應用封裝庫裡面呼叫的路徑,推測錯誤訊息是最後一行:OSError。
拿去搜尋之後找到了論壇的討論,問題應該是程序沒有走代理,導致訪問不到。
用python連接Google失敗

有人提到把翻牆程式設定成global mode,可是我已經設定了,
還用了proxifier把terminal.app加入rule,還是失敗...只好來想辦法改code加入proxy了。

從上面的錯誤訊息裡面可以看到,出現錯誤的是在22行。
  File "quickstart.py", line 22, in <module>
    creds = tools.run_flow(flow, store)

似乎是在這個stackoverflow問題看到run_flow設定http參數,並設定其中的proxy info。
python - setting proxy on httplib2 - Stack Overflow
oauth 2.0 - Which flag for run_flow() will simulate the now deprecated run() - Stack Overflow

改完之後再重新執行一次,又出現錯誤了。
Traceback (most recent call last):
  File "quickstart.py", line 24, in <module>
    service = build('drive', 'v3', http=creds.authorize(Http()))
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery.py", line 222, in build
    requested_url, discovery_http, cache_discovery, cache)
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery.py", line 269, in _retrieve_discovery_doc
    resp, content = http.request(actual_url)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/transport.py", line 175, in new_request
    redirections, connection_type)
  File "/usr/local/lib/python3.6/site-packages/oauth2client/transport.py", line 282, in request
    connection_type=connection_type)
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1514, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1264, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1187, in _conn_request
    conn.connect()
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1050, in connect
    raise socket_err
  File "/usr/local/lib/python3.6/site-packages/httplib2/__init__.py", line 1011, in connect
    sock.connect((self.host, self.port))
OSError: [Errno 65] No route to host

出現的是一樣的錯誤訊息,看起來可以照上面的概念去處理!
  File "quickstart.py", line 24, in <module>
    service = build('drive', 'v3', http=creds.authorize(Http()))

照上面的作法,把Http()改成Http(proxy_info = p)。
改完之後執行成功了!

最後附上完整程式碼。

留言

這個網誌中的熱門文章

[python] nginx + uwsgi + django 環境部署

台灣人在上海辦台胞證換發