本文目录导读:

针对脚本(通常指自动化脚本或程序代码)的合同文件分类归档,核心目标是自动化、结构化、可追溯,以下是一套基于脚本实现的分类归档方案,分为设计思路、具体实现步骤和示例代码三个部分。
核心设计思路
- 输入源:扫描指定文件夹(如“待归档合同”),或通过API接收文件。
- 信息提取:从PDF/Docx/图片合同中提取关键元数据(合同编号、甲方/乙方、签署日期、金额、合同类型)。
- 分类规则:基于提取的元数据(如甲方名称的首字母、合同类型、年份)自动生成文件夹层级。
- 归档执行:按规则移动或复制文件到新目录,并可能重命名。
- 日志与校验:记录每次操作,避免重复归档或错误处理。
详细实现步骤(以Python为例)
步骤1:环境准备
需要安装以下Python库:
os,shutil:文件操作pyPdf2/pdfplumber:读取PDF文本python-docx:读取Word文档pandas:处理分类规则表(如有)re:正则表达式提取数据
pip install pdfplumber python-docx pandas
步骤2:定义合同元数据结构
# 单个合同的信息字典
contract_info = {
"contract_id": "HT2023001",
"party_a": "某科技公司",
"party_b": "某服务商",
"sign_date": "2023-05-20",
"amount": 1000000.00,
"type": "技术服务合同", # 可来自文件名或内容关键词(如“采购”“租赁”“保密”)
"original_filename": "2023技术服务合同_某公司.pdf"
}
步骤3:信息提取函数(核心)
- PDF合同:用
pdfplumber逐页提取文本,然后用正则匹配“合同编号”“甲方”等。 - Word合同:用
python-docx读取段落或表格。 - 命名规范:若文件名已包含信息(如“HT2023-001-某公司-采购.pdf”),可优先解析文件名。
import re, pdfplumber
def extract_from_pdf(filepath):
text = ""
with pdfplumber.open(filepath) as pdf:
for page in pdf.pages:
text += page.extract_text()
# 示例正则:提取合同类型(假设文本包含“本合同为……合同”)
type_match = re.search(r'本合同为[\s]*([\u4e00-\u9fa5]+)[\s]*合同', text)
contract_type = type_match.group(1) if type_match else "其他"
# 类似提取其他字段...
return contract_type # 返回结构化字典
步骤4:分类规则引擎
def classify_rule(info):
"""
根据合同信息生成归档路径
示例规则:
/归档根目录/
{年度}/
{合同类型}/
{甲方首字母}/
{重命名后的文件}
"""
year = info['sign_date'][:4] if info['sign_date'] else "未知年份"
ctype = info['type'] if info['type'] else "其他"
# 甲方名称拼音首字母(可引入pypinyin库)
first_letter = get_first_letter(info['party_a'])
target_dir = os.path.join(ARCHIVE_ROOT, year, ctype, first_letter)
os.makedirs(target_dir, exist_ok=True)
return target_dir
步骤5:执行归档与日志
import shutil, datetime, csv
def archive_file(src_path, info):
target_dir = classify_rule(info)
# 重命名:合同编号_原始文件名(避免重名)
new_name = f"{info['contract_id']}_{info['original_filename']}"
target_path = os.path.join(target_dir, new_name)
shutil.move(src_path, target_path) # 或 copy2
# 写入日志.csv
with open('archive_log.csv', 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([datetime.now(), src_path, target_path, info['contract_id']])
步骤6:主流程循环扫描
import glob
ARCHIVE_ROOT = "D:/合同归档"
INPUT_FOLDER = "D:/待归档"
for filename in os.listdir(INPUT_FOLDER):
filepath = os.path.join(INPUT_FOLDER, filename)
if not os.path.isfile(filepath):
continue
# 跳过已归档标记(如文件名包含"_已归档")
if "_已归档" in filename:
continue
try:
info = extract_from_pdf(filepath) # 或 extract_from_docx
if info:
archive_file(filepath, info)
# 重命名原文件(可选)防止重复处理
os.rename(filepath, filepath.replace(".pdf", "_已归档.pdf"))
else:
# 无法提取则移到“未识别”文件夹
move_to_unknown(filepath)
except Exception as e:
log_error(filepath, str(e))
进阶优化建议
- 手写符号或样本的识别:如果合同中有手写的分类编号或签名,可结合OCR(如
pytesseract或百度API)进行识别。 - 重复归档检测:通过MD5哈希或合同编号,确保同一份合同不被重复归档。
- 性能提升:使用
multiprocessing或asyncio批量处理上百份文件。 - 用户交互:提供一个简单的GUI(如
tkinter)让用户手动确认提取的信息,避免误归。 - 分类规则动态化:将规则存储在JSON或Excel中,方便非技术人员修改(如增加“年份→客户→合同类型”的层级)。
示例流程示意图
[待归档文件夹]
├── 采购合同_华为_20231001.pdf
├── 技术服务合同_腾讯_2023.pdf
└── 租赁合同_利丰.docx
运行脚本后,自动生成:
[归档根目录]
├── 2023/
│ ├── 采购/
│ │ └── H/
│ │ └── HT2023-001_采购合同_华为_20231001.pdf
│ ├── 技术服务/
│ │ └── T/
│ │ └── HT2023-002_技术服务合同_腾讯_2023.pdf
│ └── 租赁/
│ └── L/
│ └── HT2023-003_租赁合同_利丰.docx
└── 未识别/
└── 模糊合同.png
常见问题处理
- 文件太模糊:设置置信度阈值,低于阈值时放入“待人工确认”文件夹。
- 合同类型识别不准:可采用关键词权重匹配(如“采购”出现5次以上才判为采购合同)。
- 存档路径冲突:生成唯一文件编号(如UUID),或判断目标目录是否已有同名文件并加后缀。
如果需要完整可运行的示例代码(包括PDF提取、Excel规则表、多线程扫描),我可以进一步提供。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播