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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:33:24