python - 使用谷歌驱动python API分块部分下载
问题描述
google drive
可以使用该方法MediaIoBaseDownload
与由request = service.files().get_media(fileId=<id>)
.
可以通过修改Range
HTTP 标头的参数来完成部分下载,如本文所述:
request.headers["Range"] = "bytes={}-{}".format(start, start+length)
但是,两者不能组合,因为标头中的字节范围信息被忽略MediaIoBaseDownload
。
如何以分块方式完成部分下载?
解决方案
这是一个部分答案,它解决了范围的起始字节,而不是结束字节。
正如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
推荐阅读
- python - 有没有办法让多个线程在 python 中监听同一个套接字?
- tensorflow - 如何对不同长度的时间序列图像序列进行分类
- function - 模块化以在 Kotlin 中创建具有可变类型的函数
- wagtail - 如何继续在 Wagtail / Draftail 中对有序列表进行编号?
- validation - Web 应用程序如何拒绝 cookie 域中的通配符
- hive - 如何创建带标题的 Hive 表
- algorithm - 我如何在这个组合函数上使用尾调用优化?
- r - 如何删除ggplot区域边框?
- ios - SceneKit 球体法线似乎随着相机移动而改变?
- python - 使用递归在 Python 中查找长度为 k 的最频繁字符串