尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

影刀RPA 压缩与解压:ZIP文件的处理

影刀RPA 压缩与解压:ZIP文件的处理
📅 发布时间:2026/7/13 2:31:30

影刀RPA 压缩与解压:ZIP文件的处理

作者:林焱

什么情况用

你的影刀流程每天采集大量数据文件,磁盘空间不够用了,需要把历史数据压缩归档?你从网站下载了一个ZIP文件,需要自动解压后处理里面的数据?你想把多个采集结果文件打包成一个ZIP发送邮件?

ZIP文件处理是文件管理的常见需求。Python的zipfile模块提供了完整的ZIP压缩和解压功能,在影刀RPA的Python代码块中可以直接使用。

本文讲清楚:怎么创建ZIP、怎么解压ZIP、怎么处理中文文件名乱码。


怎么做

一、创建ZIP文件

importzipfileimportos# ===== 压缩单个文件 =====defzip_single_file(filepath,zip_path):"""把单个文件压缩成zip"""withzipfile.ZipFile(zip_path,'w',zipfile.ZIP_DEFLATED)aszf:zf.write(filepath,os.path.basename(filepath))print(f"已压缩{filepath}→{zip_path}")# ===== 压缩多个文件 =====defzip_multiple_files(filepaths,zip_path):"""把多个文件压缩成一个zip"""withzipfile.ZipFile(zip_path,'w',zipfile.ZIP_DEFLATED)aszf:forfilepathinfilepaths:ifos.path.exists(filepath):zf.write(filepath,os.path.basename(filepath))print(f" 添加:{filepath}")else:print(f" 跳过(不存在):{filepath}")print(f"已压缩{len(filepaths)}个文件 →{zip_path}")# ===== 压缩整个文件夹 =====defzip_directory(dir_path,zip_path):"""把整个文件夹压缩成zip"""withzipfile.ZipFile(zip_path,'w',zipfile.ZIP_DEFLATED)aszf:forroot,dirs,filesinos.walk(dir_path):forfileinfiles:filepath=os.path.join(root,file)# 保持相对路径结构arcname=os.path.relpath(filepath,dir_path)zf.write(filepath,arcname)print(f"已压缩文件夹{dir_path}→{zip_path}")# 使用zip_single_file("data/report.xlsx","data/report.zip")zip_multiple_files(["data/a.xlsx","data/b.xlsx","data/c.csv"],"data/multiple.zip")zip_directory("data/output","data/output_backup.zip")

二、解压ZIP文件

importzipfileimportos# ===== 解压到指定目录 =====defunzip_file(zip_path,extract_dir):"""解压zip文件到指定目录"""withzipfile.ZipFile(zip_path,'r')aszf:zf.extractall(extract_dir)print(f"已解压{zip_path}→{extract_dir}")# ===== 解压并获取文件列表 =====defunzip_and_list(zip_path,extract_dir):"""解压并返回文件列表"""extracted_files=[]withzipfile.ZipFile(zip_path,'r')aszf:forinfoinzf.infolist():# 跳过目录ifinfo.is_dir():continue# 解压单个文件zf.extract(info,extract_dir)extracted_path=os.path.join(extract_dir,info.filename)extracted_files.append({"name":info.filename,"path":extracted_path,"size":info.file_size,"compressed_size":info.compress_size,})print(f"解压完成,共{len(extracted_files)}个文件:")forfinextracted_files:print(f"{f['name']}({f['size']}bytes)")returnextracted_files# ===== 只读取ZIP内的文件内容(不解压到磁盘) =====defread_zip_content(zip_path,filename):"""直接读取ZIP内文件内容,不解压"""withzipfile.ZipFile(zip_path,'r')aszf:withzf.open(filename)asf:content=f.read()returncontent# 读取ZIP内的文本文件text=read_zip_content("data.zip","readme.txt").decode("utf-8")print(text)# 读取ZIP内的CSV文件importioimportcsv csv_bytes=read_zip_content("data.zip","data.csv")csv_reader=csv.reader(io.TextIOWrapper(io.BytesIO(csv_bytes),encoding="utf-8"))forrowincsv_reader:print(row)

三、查看ZIP内容(不解压)

deflist_zip_contents(zip_path):"""列出ZIP文件内容"""withzipfile.ZipFile(zip_path,'r')aszf:print(f"ZIP文件:{zip_path}")print(f"文件数量:{len(zf.namelist())}")print("-"*60)forinfoinzf.infolist():ifinfo.is_dir():print(f" [目录]{info.filename}")else:ratio=(1-info.compress_size/info.file_size)*100ifinfo.file_size>0else0print(f"{info.filename}")print(f" 原始:{info.file_size:,}bytes, 压缩后:{info.compress_size:,}bytes, 压缩率:{ratio:.1f}%")# 总计total_size=sum(f.file_sizeforfinzf.infolist()ifnotf.is_dir())total_compressed=sum(f.compress_sizeforfinzf.infolist()ifnotf.is_dir())print("-"*60)print(f" 总计:{total_size:,}bytes →{total_compressed:,}bytes")list_zip_contents("data/output.zip")

四、处理中文文件名乱码

importzipfileimportosdefunzip_with_chinese_names(zip_path,extract_dir):""" 解压ZIP文件,正确处理中文文件名 解决中文文件名乱码问题 """withzipfile.ZipFile(zip_path,'r')aszf:forinfoinzf.infolist():# 检测文件名编码filename=info.filename# ZIP文件名编码问题:# Windows创建的ZIP用GBK编码文件名# 但Python的zipfile默认用UTF-8解码# 需要尝试不同编码try:# 先尝试UTF-8filename.encode('utf-8').decode('utf-8')except(UnicodeDecodeError,UnicodeEncodeError):try:# 尝试GBKfilename=filename.encode('cp437').decode('gbk')except:try:filename=filename.encode('cp437').decode('utf-8')except:pass# 保持原样ifinfo.is_dir():dir_path=os.path.join(extract_dir,filename)os.makedirs(dir_path,exist_ok=True)continue# 解压文件data=zf.read(info)output_path=os.path.join(extract_dir,filename)# 确保目录存在os.makedirs(os.path.dirname(output_path),exist_ok=True)withopen(output_path,'wb')asf:f.write(data)print(f"解压:{filename}")

五、增量压缩与更新

defappend_to_zip(zip_path,files_to_add):"""向已有的ZIP文件中追加文件"""withzipfile.ZipFile(zip_path,'a',zipfile.ZIP_DEFLATED)aszf:forfilepathinfiles_to_add:ifos.path.exists(filepath):zf.write(filepath,os.path.basename(filepath))print(f"追加:{filepath}")else:print(f"跳过(不存在):{filepath}")defupdate_zip(zip_path,file_to_update):""" 更新ZIP中的文件 zipfile不支持直接更新,需要重建 """importtempfile temp_zip=tempfile.mktemp(suffix=".zip")withzipfile.ZipFile(zip_path,'r')aszf_old:withzipfile.ZipFile(temp_zip,'w',zipfile.ZIP_DEFLATED)aszf_new:# 复制不需要更新的文件foriteminzf_old.infolist():ifitem.filename!=os.path.basename(file_to_update):zf_new.writestr(item,zf_old.read(item.filename))# 添加更新后的文件zf_new.write(file_to_update,os.path.basename(file_to_update))# 替换原文件os.replace(temp_zip,zip_path)print(f"已更新{zip_path}中的{file_to_update}")

六、实战:自动归档旧文件

importzipfileimportosimporttimefromdatetimeimportdatetime,timedeltadefauto_archive_old_files(source_dir,archive_dir,days_old=30):""" 自动归档超过指定天数的文件 把旧文件按月份压缩归档 """ifnotos.path.exists(archive_dir):os.makedirs(archive_dir)cutoff_time=time.time()-days_old*86400archives={}# {月份: [文件列表]}# 找出需要归档的文件forfilenameinos.listdir(source_dir):filepath=os.path.join(source_dir,filename)ifnotos.path.isfile(filepath):continuefile_mtime=os.path.getmtime(filepath)iffile_mtime<cutoff_time:# 按月份分组file_date=datetime.fromtimestamp(file_mtime)month_key=file_date.strftime("%Y-%m")ifmonth_keynotinarchives:archives[month_key]=[]archives[month_key].append(filepath)# 按月份压缩归档formonth,filesinarchives.items():zip_path=os.path.join(archive_dir,f"archive_{month}.zip")# 如果归档文件已存在,追加ifos.path.exists(zip_path):append_to_zip(zip_path,files)else:zip_multiple_files(files,zip_path)# 归档后删除原文件forfilepathinfiles:os.remove(filepath)print(f"已归档并删除:{filepath}")print(f"归档完成:{len(archives)}个月份, 共{sum(len(f)forfinarchives.values())}个文件")# 使用:归档30天前的文件auto_archive_old_files("D:/data/output","D:/data/archive",days_old=30)

七、带密码的ZIP文件

# Python标准库zipfile只支持解压带密码的ZIP,不支持创建# 解压带密码的ZIP:defunzip_with_password(zip_path,extract_dir,password):"""解压带密码的ZIP文件"""withzipfile.ZipFile(zip_path,'r')aszf:try:zf.extractall(extract_dir,pwd=password.encode())print("解压成功")returnTrueexceptRuntimeErrorase:if"password"instr(e).lower():print("密码错误")else:print(f"解压失败:{e}")returnFalse# 使用unzip_with_password("secret.zip","output","mypassword")# 如果需要创建带密码的ZIP,需要第三方库pyzipper# pip install pyzipper# import pyzipper# with pyzipper.AESZipFile('secret.zip', 'w', compression=pyzipper.ZIP_DEFLATED, encryption=pyzipper.WZ_AES) as zf:# zf.setpassword(b'mypassword')# zf.write('data.xlsx')

有什么坑

坑1:ZIP_DEFLATED未安装报错

现象:zipfile.ZipFile(path, 'w', zipfile.ZIP_DEFLATED)报错RuntimeError: Compression requires the (missing) zlib module。

原因:Python安装时没有包含zlib库(某些精简版Python会出现)。

解决:用zipfile.ZIP_STORED代替ZIP_DEFLATED(只打包不压缩),或者安装完整版Python。影刀RPA自带的Python通常包含zlib,不会有此问题。

坑2:解压时路径穿越攻击

现象:ZIP文件中包含../../../etc/passwd这样的路径,解压时文件被写到ZIP目录外面。

解决:解压前检查每个文件的路径,拒绝包含..的路径:

defsafe_extract(zip_path,extract_dir):withzipfile.ZipFile(zip_path,'r')aszf:forinfoinzf.infolist():# 检查路径安全性target=os.path.join(extract_dir,info.filename)ifnotos.path.abspath(target).startswith(os.path.abspath(extract_dir)):print(f"安全警告:跳过可疑路径{info.filename}")continuezf.extract(info,extract_dir)

坑3:大文件压缩内存占用高

现象:压缩一个2GB的文件,内存占用飙升。

原因:zf.write()默认会一次性读取整个文件到内存。

解决:对大文件使用zf.writestr()分块写入,或者直接使用zf.write()(它底层是流式写入,不会一次性读取全部)。如果还是内存高,检查是否在读取ZIP内容时用了zf.read()一次性读取。

坑4:影刀变量不能直接传文件路径列表

现象:在影刀中用【获取文件列表】获取了文件路径列表,传给Python代码块进行压缩,但路径格式不对。

解决:影刀的文件列表变量可能是字符串用分隔符拼接的,需要在Python代码块中解析。或者直接在Python代码块中用os.listdir()获取文件列表,不依赖影刀变量传递。

坑5:解压后文件被锁

现象:解压ZIP文件后,想删除解压的文件但提示"文件被占用"。

原因:解压后文件可能被其他程序(如Excel)打开,或者Python的文件句柄没关闭。

解决:确保所有文件操作都用了with语句或手动关闭。在删除前用time.sleep(1)等一下系统释放文件锁。在影刀中,确保没有其他指令正在使用这些文件。

相关新闻

  • 5分钟掌握猫抓:浏览器资源嗅探与媒体捕获的终极指南
  • AI医疗应用的技术边界与伦理实践:从视觉刺激到真实疗效
  • 金融数据分析入门:先学财报、指标还是工具?

最新新闻

  • CPCC_S_TASK_LIST_MAINTAIN BAPI 实战:3种操作模式(C/M/D)批量分配工艺路线组件
  • AI推理攻击:模型API如何被合法调用‘说漏嘴’
  • 高中生真实项目交付:从Firebase+React到PWA的工程实践
  • 多维聚合:从GROUP BY到OLAP引擎的数据升维实践
  • 2026年7月山东回转寿司设备/菏泽皮带餐饮寿司设备公司选择策略_山东鼎盛科技有限公司 - 品牌宣传支持者
  • 3分钟掌握ComfyUI-Inpaint-Nodes:让AI图像修复变得简单高效

日新闻

  • AI推荐结果怎么优化:适合深圳少儿素质培训机构的GEO服务商哪家好?全程零代码SAAS操作
  • RAG 实战教学完全指南
  • 企业级API网关架构深度解析:IBM Microgateway的技术实现与选型指南

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号