0

使用谷歌的API的Python客戶端錯誤google-api-python-client==1.6.2與媒體下載

fh = io.BytesIO() 
request = self.drive_service.files().export_media(
    fileId='1fwshPVKCACXgNxJtmGN94X-9RRrukiDs9q4s-n0nGlM', 
    mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document' 
) 
downloader = MediaIoBaseDownload(fh, request, chunksize=1024) 
done = False 
while done is False: 
    status, done = downloader.next_chunk() 
    print "Download ", status.progress(), downloader._progress, downloader._total_size, done 

輸出:

Download 0.0 973060 None False 
Download 0.0 1946120 None False 
Download 0.0 2919180 None False 
Download 0.0 3892240 None False 
Download 0.0 4865300 None False 
Download 0.0 5838360 None False 
Download 0.0 6811420 None False 
Download 0.0 7784480 None False 
Download 0.0 8757540 None False 
... 

下載文件的文件大小爲973060個字節。所以,庫忽略chunksize參數並沒有停止。永不止步。

所以,任何人都可以告訴我我的要求是否過高或圖書館如此糟糕?

+0

奇怪。你有沒有嘗試下載不同大小的文件,並看看行爲是否仍然是一樣的? –

+0

我嘗試了不同的塊大小和文件。我知道'chunksize'總是被忽略(一個文件被下載到一個請求中)並且沒有無限循環地下載許多其他文件。我認爲這個文件類型的主要問題。它是由模板創建的Google文檔。 –

回答

0

下面的示例如何?

樣品:

request = self.drive_service.files().export_media(
    fileId='1fwshPVKCACXgNxJtmGN94X-9RRrukiDs9q4s-n0nGlM', 
    mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document' 
).execute() 
with open('sample.docx', 'wb') as f: 
    f.write(request) 

如果不工作,我很抱歉。

+0

是的。有用。謝謝。這對我很有用,因爲Google文檔中沒有這樣的示例。 –

+0

對不起,我不能投票 - 信譽低。 –

+0

@Alexandr Lupandin沒問題。也謝謝你的關注。 – Tanaike

0

The google-api-python-client library has a bug where downloads will never be considered done if the Content-length or Content-range header is missing.

而且由於drive.files.export不支持分塊下載它不返回Content-lengthContent-range頭。

只需在HttpRequest上調用execute即可下載該文件,因爲drive.files.export將始終在一個請求中導出整個文件。

如果您仍想使用MediaIoBaseDownload作爲更一般的解決方法,則可以檢查MediaDownloadProgress.total_size是否爲None

fh = io.BytesIO() 
request = service.files().export_media(fileId=file_id, mimeType=mime_type) 
downloader = MediaIoBaseDownload(fh, request) 

done = False 
while not done: 
    status, done = downloader.next_chunk() 
    if status.total_size is None: 
     # https://github.com/google/google-api-python-client/issues/15 
     done = True 
+0

謝謝你對這個問題的詳細解釋。但爲什麼在這種情況下使用'MediaIoBaseDownload'?我認爲最好的解決方案就是簡單地調用'execute()',如上所述。例如,我的代碼將爲 或簡單地 'content = service。.fh = io.BytesIO()。write(service.files().port_media(fileId = file_id,mimeType = mime_type).execute())。 ()。export_media(fileId = file_id,mimeType = mime_type).execute()' –

+0

@AlexandrLupandin更新了我的答案,並給出了一個更通用的解決方法。 – danielx