You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建下载含指定图片列表的ZIP文件 修复路径嵌套与图片存储问题

问题根因

原代码存在三个核心问题:

  • 写入文件时直接将URL字符串作为内容存储,没有发起HTTP请求拉取URL对应的图片二进制数据,最终压缩包内的文件只有URL文本,不存在实际图片内容。
  • 调用zip_file.write()时仅传入了文件的本地绝对路径,zip模块默认会将完整路径结构全部打包进压缩包,最终解压就会出现多层嵌套的冗余目录。
  • 错误使用StringIO存储二进制格式的zip内容,存在压缩包损坏的风险,二进制数据应该使用BytesIO作为缓冲区。
  • 本地临时目录的逻辑完全多余,会产生不必要的磁盘IO和临时文件残留问题。
最优修复方案

不需要在服务端创建本地临时文件夹,所有图片拉取、zip打包操作全在内存中完成,性能更高也没有文件残留问题,修正后代码如下:

import requests
import zipfile
from io import BytesIO
from django.http import HttpResponse

def download_image_zip(request):
    image_list = ['https://example.com/media/file1.jpg', 'https://example.com/media/file2.jpg']
    # 初始化内存二进制缓冲区
    buffer = BytesIO()
    # 压缩时启用DEFLATED算法减小zip体积
    with zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
        for idx, img_url in enumerate(image_list):
            # 拉取图片实际二进制内容
            img_resp = requests.get(img_url, timeout=10)
            # 请求失败直接抛出异常,避免写入无效内容
            img_resp.raise_for_status()
            # 从URL中截取原始文件名
            file_name = img_url.rsplit("/", 1)[-1]
            # 指定文件在zip包内的存储路径,统一放在img目录下
            zip_inner_path = f"img/{file_name}"
            # 直接将图片内容写入zip,无需落盘
            zip_file.writestr(zip_inner_path, img_resp.content)
    # 将指针移到缓冲区起始位置
    buffer.seek(0)
    resp = HttpResponse(buffer.getvalue(), content_type="application/x-zip-compressed")
    resp['Content-Disposition'] = 'attachment; filename=gik.zip'
    return resp

运行以上代码生成的zip包,解压后结构完全符合预期:

gik/
└── img/
    ├── file1.jpg
    └── file2.jpg
保留本地临时文件的修改方式

如果因为特殊业务要求必须先把图片存到本地临时目录再打包,只需要修改两处逻辑即可:

  1. 写本地文件时先拉取图片二进制内容,不要直接写入URL字符串,同时给文件加上对应图片后缀,避免解压后系统无法识别文件格式
  2. 写入zip时通过arcname参数指定文件在压缩包内的相对路径,过滤掉本地绝对路径
    核心修改片段:
# 拉取图片写入本地目录的修正逻辑
for i, img_url in enumerate(image_list):
    img_resp = requests.get(img_url, timeout=10)
    img_resp.raise_for_status()
    # 提取文件后缀
    suffix = img_url.rsplit(".", 1)[-1]
    save_path = os.path.join(folder, f"{i}.{suffix}")
    with open(save_path, 'wb') as f:
        f.write(img_resp.content)

# 写入zip的修正逻辑
for filename in os.listdir(folder):
    file_abs_path = os.path.join(folder, filename)
    # arcname指定压缩包内的相对路径,不会带入本地绝对路径
    zip_file.write(file_abs_path, arcname=f"img/{filename}")

内容的提问来源于stack exchange,提问作者D_P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:30:54