Python脚本—1.提取压缩包中的pdf文件
·
Python脚本:
在n个压缩包中,提取pdf文件。本文中代码有Qoder CN生成。
在整理毕业设计的材料时,需要让学生提交一个最终材料的压缩包,另外提交一个论文和指导手册的pdf文件。但是很多同学忘记交pdf了,那就用下面的程序提取。
1. 下面是5个同学的压缩包,压缩包中包含pdf文件,我需要把他们的pdf文件提取出来。

2. 使用程序:需要修改程序中的第224行SOURCE_FOLDER,改为自己的文件夹路径。
import os
import zipfile
import tarfile
import shutil
import subprocess
from pathlib import Path
"""_summary_
把压缩包中的 PDF 文件解压并保存为单独的文件,在最终材料中提取论文与指导手册得pdf文件
Returns:
_type_: _description_
"""
# 尝试导入可选的库以支持更多格式
try:
import py7zr
HAS_7Z_LIB = True
except ImportError:
HAS_7Z_LIB = False
try:
import rarfile
HAS_RAR_LIB = True
except ImportError:
HAS_RAR_LIB = False
# 配置 7-Zip 路径 (根据你的安装位置修改)
# 优先尝试系统 PATH 中的 7z,如果没有,尝试常见安装路径
SEVEN_ZIP_PATH = '7z'
def is_tool_available(cmd):
"""检查命令行工具是否可用"""
try:
subprocess.run([cmd, '--help'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=5)
return True
except (FileNotFoundError, subprocess.TimeoutExpired):
return False
if not is_tool_available('7z'):
possible_paths = [r"D:\InstallProgram\7-Zip\7z.exe"]
for p in possible_paths:
if os.path.exists(p):
SEVEN_ZIP_PATH = p
break
def get_unique_filename(filepath):
"""如果文件已存在,生成一个新的唯一文件名 (例如 file(1).pdf)"""
if not os.path.exists(filepath):
return filepath
base, ext = os.path.splitext(filepath)
counter = 1
while os.path.exists(filepath):
filepath = f"{base}({counter}){ext}"
counter += 1
return filepath
def flatten_output_directory(output_dir):
"""
将 output_dir 下所有子文件夹中的文件移动到 output_dir 根目录
并删除空的子文件夹
"""
if not os.path.exists(output_dir):
return
# 遍历目录树
for root, dirs, files in os.walk(output_dir, topdown=False):
# 跳过根目录本身
if root == output_dir:
continue
# 移动文件到根目录
for filename in files:
src_path = os.path.join(root, filename)
dst_path = os.path.join(output_dir, filename)
# 处理文件名冲突
dst_path = get_unique_filename(dst_path)
try:
shutil.move(src_path, dst_path)
# print(f" 移动文件: {filename} 到根目录")
except Exception as e:
print(f" 移动文件失败 {filename}: {e}")
# 删除空文件夹 (os.walk topdown=False 保证先处理子目录)
try:
if not os.listdir(root): # 如果文件夹为空
os.rmdir(root)
except Exception as e:
pass # 忽略删除错误
def extract_pdf_from_zip(zip_path, output_dir):
"""从 zip 文件中提取 PDF (支持 GBK 编码文件名)"""
try:
with zipfile.ZipFile(zip_path, 'r', metadata_encoding='gbk') as z:
for file_info in z.infolist():
if file_info.is_dir():
continue
if file_info.filename.lower().endswith('.pdf'):
filename = os.path.basename(file_info.filename)
if not filename or not filename.strip():
continue
target_path = os.path.join(output_dir, filename)
target_path = get_unique_filename(target_path)
try:
with z.open(file_info) as source, open(
target_path, 'wb') as target:
shutil.copyfileobj(source, target)
except Exception as e:
print(f" 提取 ZIP 中的 PDF 失败 {filename}: {e}")
except Exception as e:
print(f"错误: 无法打开或解压 ZIP 文件 {zip_path}: {e}")
def extract_pdf_from_tar(tar_path, output_dir):
"""从 tar/tar.gz 文件中提取 PDF"""
mode = 'r:gz' if tar_path.endswith('.gz') else 'r'
try:
with tarfile.open(tar_path, mode) as t:
for member in t.getmembers():
if member.isfile() and member.name.lower().endswith('.pdf'):
filename = os.path.basename(member.name)
if filename:
target_path = os.path.join(output_dir, filename)
target_path = get_unique_filename(target_path)
with t.extractfile(member) as source, open(
target_path, 'wb') as target:
shutil.copyfileobj(source, target)
except Exception as e:
print(f"错误: 无法解压 {tar_path}: {e}")
def extract_pdf_from_7z(sevenz_path, output_dir):
"""从 7z 文件中仅提取 PDF"""
_extract_archive_with_filter(sevenz_path, output_dir, '7z')
def extract_pdf_from_rar(rar_path, output_dir):
"""从 rar 文件中仅提取 PDF"""
_extract_archive_with_filter(rar_path, output_dir, 'rar')
def _extract_archive_with_filter(archive_path, output_dir, archive_type):
"""
通用函数:使用 7-Zip 命令行工具,先列表筛选,再仅提取 PDF
archive_type: '7z' or 'rar'
"""
if not os.path.exists(archive_path):
print(f"错误: 文件不存在 {archive_path}")
return
# 1. 列出压缩包内的所有文件
# 7z l "archive.rar" -ba -slt 列出详细技术信息,便于解析
cmd_list = [SEVEN_ZIP_PATH, 'l', archive_path, '-ba', '-slt']
pdf_files_in_archive = []
try:
result = subprocess.run(cmd_list,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if result.returncode != 0:
print(
f" 无法列出 {archive_type} 内容: {result.stderr.decode('gbk', errors='ignore')}"
)
return
# 解析输出,寻找 Path 行
output_text = result.stdout.decode('gbk',
errors='ignore') # 7z 中文输出通常是 gbk
lines = output_text.splitlines()
current_path = None
for line in lines:
if line.startswith('Path = '):
current_path = line[7:].strip()
if current_path.lower().endswith('.pdf'):
pdf_files_in_archive.append(current_path)
except Exception as e:
print(f" 解析 {archive_type} 列表时出错: {e}")
return
if not pdf_files_in_archive:
print(f" 未在 {os.path.basename(archive_path)} 中找到 PDF 文件")
return
# 2. 仅提取筛选出的 PDF 文件
# 7z x "archive.rar" -o"output_dir" -y "file1.pdf" "file2.pdf"
if pdf_files_in_archive:
# 构建提取命令
cmd_extract = [
SEVEN_ZIP_PATH, 'x', archive_path, f'-o{output_dir}', '-y'
] + pdf_files_in_archive
try:
result = subprocess.run(cmd_extract,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if result.returncode == 0:
print(
f" 成功从 {archive_type} 中提取了 {len(pdf_files_in_archive)} 个 PDF"
)
# 3. 扁平化处理:将子文件夹中的 PDF 移到根目录
flatten_output_directory(output_dir)
else:
err_msg = result.stderr.decode('gbk', errors='ignore')
print(f" 提取 {archive_type} 中的 PDF 失败: {err_msg}")
except Exception as e:
print(f" 执行提取命令时出错: {e}")
def main():
# 配置部分
SOURCE_FOLDER = 'C:/Users/Downloads/软件工程2309-2310-第四章作业/(pdf)'
OUTPUT_FOLDER = 'extracted_pdfs'
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
supported_extensions = ('.zip', '.tar', '.gz', '.tgz', '.7z', '.rar')
processed_count = 0
for filename in os.listdir(SOURCE_FOLDER):
file_path = os.path.join(SOURCE_FOLDER, filename)
if not os.path.isfile(file_path):
continue
lower_name = filename.lower()
if not any(lower_name.endswith(ext) for ext in supported_extensions):
continue
print(f"正在处理: {filename}")
try:
if lower_name.endswith('.zip'):
extract_pdf_from_zip(file_path, OUTPUT_FOLDER)
elif lower_name.endswith(('.tar', '.gz', '.tgz')):
extract_pdf_from_tar(file_path, OUTPUT_FOLDER)
elif lower_name.endswith('.7z'):
extract_pdf_from_7z(file_path, OUTPUT_FOLDER)
elif lower_name.endswith('.rar'):
extract_pdf_from_rar(file_path, OUTPUT_FOLDER)
processed_count += 1
except Exception as e:
print(f"处理文件 {filename} 时发生未知错误: {e}")
print(f"\n完成! 共处理了 {processed_count} 个压缩包。")
print(f"PDF 文件已保存到: {os.path.abspath(OUTPUT_FOLDER)}")
if __name__ == '__main__':
main()
3.运行程序,显示处理了5个压缩包,提取的文件放到了extracted_pdfs文件夹中。


提取pdf文件完成![]()
![]()
![]()
本文中代码有Qoder CN生成。
阿里云推出的AI智能体产品系列
Qoder CN,阿里云推出的AI智能体产品系列,覆盖软件开发与日常办公多元场景,包含面向编码场景的Qoder CN、面向日常工作的QoderWork CN、Qoder CN CLI等子产品。Qoder CN前身为阿里云旗下智能编码助手通义灵码。
更多推荐



所有评论(0)