首页 > 解决方案 > 使用谷歌驱动python API分块部分下载

问题描述

google drive可以使用该方法MediaIoBaseDownload与由request = service.files().get_media(fileId=<id>).

可以通过修改RangeHTTP 标头的参数来完成部分下载,如本文所述:

request.headers["Range"] = "bytes={}-{}".format(start, start+length)

但是,两者不能组合,因为标头中的字节范围信息被忽略MediaIoBaseDownload

如何以分块方式完成部分下载?

标签: pythongoogle-drive-api

解决方案


这是一个部分答案,它解决了范围的起始字节,而不是结束字节。

正如Tanaike在评论中指出的那样,MediaIoBaseDownload忽略用户提供的 HTTP Range。一个范围,指定如下:

request.headers["Range"] = "bytes={}-{}".format(start, start+length)

实际上被添加到self._headers构造MediaIoBaseDownload函数中,但在第一次调用next_chunk方法时被立即覆盖,其中headers['range']设置为'bytes=%d-%d' % (self._progress, self._progress + self._chunksize). 在第一次调用时,self._progress=0(由构造函数设置),因此该方法将始终从文件的第一个(零)字节开始下载。

有一些简单的方法可以改变这一点。我们可以检查是否request.headers['Range']存在并解析指定的字节位置。或者,我们可以通过向构造函数添加额外的关键字参数来直接向调用者公开行为,以传递开始和结束字节位置。

以下补丁(针对 1.7.11 版本googleapiclient)采用向构造函数添加start关键字参数的方法MediaIoBaseDownload,以便可以从Nth字节开始下载。如果未指定起始字节,则默认从文件开头下载。由于尚未实现对结束字节位置的支持,因此下载将持续到EOF.

--- googleapiclient/http.py.orig    2019-08-05 12:24:31.000000000 -0700
+++ googleapiclient/http.py 2020-01-19 18:31:56.785404831 -0800
@@ -632,7 +632,7 @@
   """

   @util.positional(3)
-  def __init__(self, fd, request, chunksize=DEFAULT_CHUNK_SIZE):
+  def __init__(self, fd, request, chunksize=DEFAULT_CHUNK_SIZE, start=0):
     """Constructor.

     Args:
@@ -646,7 +646,7 @@
     self._request = request
     self._uri = request.uri
     self._chunksize = chunksize
-    self._progress = 0
+    self._progress = start
     self._total_size = None
     self._done = False

推荐阅读