使用Python os、shutil模块按PDF关键词移动文件失效问题
PDF关键词匹配自动移文件代码故障排查
原有问题描述
使用Python实现基于PDF内容关键词匹配的自动文件归类移动功能,PyCharm未检测到语法错误,但运行后无法完成预期的文件移动操作。代码为参考公开资料拼凑编写,无法定位逻辑疏漏,原有代码如下:
import os import PyPDF2 import shutil # 待匹配的客户名称列表 client_names = ["Name1", "Name2", "Name3", "Name4"] # 待扫描的PDF存放文件夹路径 scanned_path = r'path' # 生成文件夹内所有文件的路径列表 scanned_file_list = [os.path.join(scanned_path, f) for f in os.listdir(scanned_path)] print(scanned_file_list) # 遍历文件执行匹配 for document in scanned_file_list: lst = [] if document[-3] == 'pdf': file = open(document, "rb") reader=PyPDF2.PdfFileReader(file) pageObj = reader.getPage(0) text = (pageObj.extractText()) text = text.split(",") source_path = document for sentence in text: lst = [] for name in client_names: if name in sentence: if name not in lst: lst.append(name) if len(lst) > 1: file.close() elif len(lst) < 1: file.close() elif lst[0] == client_names[0]: #移动到对应客户文件夹 destination_path = r'C:\ClientFolder1' shutil.move(source_path,destination_path) elif lst[0] == client_names[1]: destination_path = r'C:\ClientFolder2' shutil.move(source_path,destination_path) elif lst[0] == client_names[2]: destination_path = r'C:\ClientFolder3' shutil.move(source_path,destination_path)
核心逻辑疏漏点
- 最致命的后缀判断错误:原代码用
document[-3] == 'pdf'判断是否为PDF文件,Python字符串索引取单个值,document[-3]仅能拿到路径倒数第3位的单个字符,永远不可能和长度为3的字符串pdf相等,导致整个PDF处理分支完全不会执行。同时该写法未兼容.PDF大写后缀的情况。 - 匹配结果存储逻辑错误:遍历按逗号拆分的文本片段时,每次循环开头都会执行
lst = []清空匹配列表,导致前一个片段匹配到的关键词直接丢失,最终无法得到完整的匹配结果。 - PDF读取范围不全:原代码仅读取PDF第一页内容,关键词如果出现在后续页面完全无法被匹配到。
- 文件句柄处理错误:一是打开PDF后没有在合适的时机关闭文件,执行移动操作时文件仍被Python进程占用,Windows系统下会直接导致移动失败;二是匹配到0个/多个客户名时直接关闭文件,但没有终止当前文件的处理循环,后续操作会触发已关闭文件的读取报错。
- 移动逻辑不完善:一是没有提前校验目标文件夹是否存在,路径不存在时
shutil.move会直接抛错;二是仅配置了前3个客户名的对应目标路径,第4个客户的匹配分支完全缺失;三是移动时仅传入目标文件夹路径,未拼接文件名,容易触发同名文件冲突。
修复后可直接运行的代码
使用前替换代码里的路径占位符为实际本地路径即可:
import os import PyPDF2 import shutil # 待匹配的客户名称与对应目标文件夹映射,新增客户直接在这里加键值对即可 client_folder_map = { "Name1": r'C:\ClientFolder1', "Name2": r'C:\ClientFolder2', "Name3": r'C:\ClientFolder3', "Name4": r'C:\ClientFolder4' # 补全第4个客户的存储路径 } # 待扫描的PDF存放文件夹路径,替换为实际本地路径 scanned_path = r'替换为你的PDF存放文件夹实际路径' # 提前自动创建不存在的目标文件夹 for folder_path in client_folder_map.values(): os.makedirs(folder_path, exist_ok=True) # 遍历文件夹内所有文件 for document in os.listdir(scanned_path): file_full_path = os.path.join(scanned_path, document) # 跳过子文件夹,只处理后缀为pdf的文件(不区分大小写) if not os.path.isfile(file_full_path): continue if os.path.splitext(document)[1].lower() != '.pdf': continue matched_client = None # 用with语句自动管理文件句柄,读取完成后自动关闭,不会出现文件占用问题 with open(file_full_path, "rb") as f: reader = PyPDF2.PdfFileReader(f) # 遍历PDF所有页面提取完整文本 full_text = "" for page_num in range(reader.numPages): page = reader.getPage(page_num) full_text += page.extractText() # 匹配客户名称,找到第一个匹配项就停止遍历 for client_name in client_folder_map.keys(): if client_name in full_text: matched_client = client_name break # 匹配到对应客户就执行文件移动 if matched_client: target_folder = client_folder_map[matched_client] # 拼接目标文件完整路径,避免同名文件冲突 target_full_path = os.path.join(target_folder, document) shutil.move(file_full_path, target_full_path) print(f"已移动文件 {document} 到 {target_folder}")
小提示:如果运行时提示PyPDF2相关属性错误,可以先执行
pip install PyPDF2==2.12.1安装适配版本后再运行。
内容的提问来源于stack exchange,提问作者Xiael
相关产品推荐
相关产品推荐

