Python requests下载图片文件:流式保存与文件命名
用requests以流式方式下载网络图片到本地,处理大文件边下边存不占内存,自动识别扩展名,适合批量保存素材、图标、照片。
场景痛点
设计稿里有几十张配图、产品库有几百张主图,手动一张张右键"图片另存为",鼠标点到冒烟。用requests把图片URL列表丢进脚本,自动下载、自动命名,几秒钟搞定,而且不用打开浏览器。
用到的库
pip install requests beautifulsoup4 lxml
完整代码
# 导入库
import os
import requests
def download_image(url, save_dir="images", filename=None):
"""下载单张图片到本地"""
# 建文件夹,存在就不报错
os.makedirs(save_dir, exist_ok=True)
# 没指定文件名就从URL里取最后一段
if filename is None:
filename = url.rstrip("/").split("/")[-1]
# 去掉URL里可能带的查询参数
filename = filename.split("?")[0]
save_path = os.path.join(save_dir, filename)
# stream=True 表示流式下载,不会一次性把整个文件读进内存
with requests.get(url, stream=True, timeout=30) as resp:
resp.raise_for_status() # 不是200就抛异常
# 边读边写,每次读8KB
with open(save_path, "wb") as f:
for chunk in resp.iter_content(chunk_size=8192):
# 过滤掉keep-alive的空块
if chunk:
f.write(chunk)
print(f"已下载:{save_path}({os.path.getsize(save_path)//1024} KB)")
return save_path
def main():
# 示例图片URL(用占位图服务做演示)
urls = [
"https://httpbin.org/image/png",
"https://httpbin.org/image/jpeg",
]
for i, url in enumerate(urls, 1):
try:
# 给文件起个有意义的名字
ext = url.split("/")[-1]
download_image(url, save_dir="images", filename=f"demo_{i}.{ext}")
except Exception as e:
print(f"下载失败 {url}:{e}")
if __name__ == "__main__":
main()
代码讲解
- 关键是
stream=True,加了这个参数后requests不会立刻把整个响应读进内存,而是建立了一个数据流,配合iter_content一块一块地读。下载几百MB的视频也不会把内存占满。 with open(save_path, "wb")以二进制写模式打开文件,图片是二进制数据,必须用wb,不能用默认的文本模式。chunk_size=8192表示每次读8KB,可以根据需要调整,文件大就调大些。resp.raise_for_status()会在状态码不是200时直接抛异常,避免把404页面的HTML当成图片存下来。os.makedirs(..., exist_ok=True)自动建目录,重复运行不会报错。
运行结果
运行后会在当前目录下生成 images 文件夹,里面有 demo_1.png、demo_2.jpeg 两张图片,控制台打印每张文件的大小。用图片查看器打开能正常显示。
注意事项
- 图片URL可能带防盗链,下载前最好带上Referer和User-Agent请求头。
- 文件名要清洗一下,去掉
/、\、:等非法字符,否则在Windows上保存失败。 - 大文件(几百MB以上)建议显示进度条,用
resp.headers.get('Content-Length')拿总大小。 - 尊重版权,下载前确认图片允许使用,不要大规模抓取受版权保护的素材。

更新时间:2026-09-14 20:49:32
上一篇:Python requests下载PDF附件:二进制保存与批量导出