点击上方“萝卜大杂烩”,选择“星标”公众号
超级无敌干货,第一时间送达!!!
大家好,我是萝卜。
通常,我们都会用 requests 库去下载,这个库用起来太方便了。
方法一
使用以下流式代码,无论下载文件的大小如何,Python 内存占用都不会增加:
def download_file(url):
local_filename = url.split('/')[-1]
# 注意传入参数 stream=True
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return local_filename如果你有对 chunk 编码的需求,那就不该传入 chunk_size 参数,且应该有 if 判断。
def download_file(url):
local_filename = url.split('/')[-1]
# 注意传入参数 stream=True
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(local_filename, 'w') as f:
for chunk in r.iter_content():
if chunk:
f.write(chunk.decode("utf-8"))
return local_filenameiter_content[1] 函数本身也可以解码,只需要传入参数 decode_unicode = True 即可。
请注意,使用 iter_content 返回的字节数并不完全是 chunk_size,它是一个通常更大的随机数,并且预计在每次迭代中都会有所不同。
方法二
使用 Response.raw[2] 和 shutil.copyfileobj[3]
import requests
import shutil
def download_file(url):
local_filename = url.split('/')[-1]
with requests.get(url, stream=True) as r:
with open(local_filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
return local_filename这将文件流式传输到磁盘而不使用过多的内存,并且代码更简单。
注意:根据文档,Response.raw 不会解码,因此如果需要可以手动替换 r.raw.read 方法
response.raw.read = functools.partial(response.raw.read, decode_content=True)
速度
方法二更快。方法一如果 2-3 MB/s 的话,方法二可以达到近 40 MB/s。
人生苦短,我用python 【神秘礼包获取方式】 点击下方公众号回复:1024
推荐阅读 点击标题可跳转 原文始发于微信公众号(萝卜大杂烩):Python 下载大文件,哪种方式速度更快
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论