加快 python 请求的下载速度(通过在节流方面采取适当的行为)

Speed up python requests download speed (by behaving appropriately around throttling)

如何使用 python 快速下载文件?

我尝试了不同的模块,例如 wget,它们的执行时间差不多。 在这个例子中,我将从 reddit

获取一个文件

https://v.redd.it/rfxd2e2zhet81/DASH_1080.mp4?source=fallback

    video_url="https://v.redd.it/rfxd2e2zhet81/DASH_1080.mp4?source=fallback"
    start = datetime.datetime.now()
    print(start)
    response = requests.get(video_url)
    stop = datetime.datetime.now()
    print(stop)
    print("status: " + str(response.status_code))

输出:

2022-04-14 15:59:52.258759
2022-04-14 16:02:03.791324
status: 200

使用 Firefox,相同的请求似乎不到一秒即可完成。

右键单击并“将视频另存为”与即时没有区别。

我通过研究有关堆栈溢出的类似问题的理解是,以下最小示例应该会导致正常的下载时间并且仅取决于我的互联网连接。 https://www.speedtest.net/ 配置为单个连接给我以下结果:

文件大小约为 20 MB,下载时间确实不应该太长。

作为对照,这个调用完成得很快。

    video_url="
    start = datetime.datetime.now()
    print(start)
    response = requests.get(video_url)
    stop = datetime.datetime.now()
    print(stop)
    print("status: " + str(response.status_code))

输出:

2022-04-14 15:58:47.022299
2022-04-14 15:58:47.418743
status: 200

我 运行 针对托管在我自己的 blob 存储上的 40 MB 文件发出相同的请求:

2022-04-14 16:07:59.304382
2022-04-14 16:08:00.729495
status: 200

根据使用 firefox 的速度差异,python 和 python 在其他目标上看起来 Python 正在被节流。

我如何使用 python 脚本并相应地运行以避免被限制?

我尝试使用 firefox 在其第一个请求中使用的 headers 无济于事 - 结果是一样的。

Using Firefox the same request completes in seemingly less than a second. A right click and "save video as" is not distinguishable from instant.

观察到您收到了代码 206 的响应。206 Partial means that requests were sent, each presumably for different part of file. After download finish parts are welded to recreate file. This might allow shorter download time, if every part is served with similar speed as when there is single download. Such behavior might be emulated using requests by sending request with appriopate headers (see linked description of 206 Partial) and using for example multiprocessing,但在此之前我必须警告您并非所有服务器都支持部分噱头,您应该仔细计算是否值得为此创建代码的额外负担你能达到的收获。

看起来解决方案是绕过 python 生态系统。 我测试了用户@Daweo在评论中提出的方案

需要安装 aria2。

video_url="https://v.redd.it/rfxd2e2zhet81/DASH_1080.mp4?source=fallback"
start = datetime.datetime.now()
print(start)
system("aria2c " + video_url)
stop = datetime.datetime.now()
print(stop)

输出是:

2022-04-15 21:38:09.693262

04/15 21:38:09 [NOTICE] Downloading 1 item(s)

04/15 21:38:10 [NOTICE] Download complete: /.../DASH_1080.mp4

Download Results:
gid   |stat|avg speed  |path/URI
======+====+===========+=======================================================
c2e8ce|OK  |    59MiB/s|/.../DASH_1080.mp4

Status Legend:
(OK):download completed.
2022-04-15 21:38:10.131280

所以这花了大约 400 毫秒。