
背景需求
【办公类-142-01】20260228插班生word转长表EXCLE(1)提取单元格内容,删除空格
https://mp.csdn.net/mp_blog/creation/editor/158471490
前代码经顺利从家长填写的插班生word里面提取了所有的文本到EXCEL里。
时间有限3月2日要上传,所以,我就从自己生成的EXCEL手动复制需要的信息到长表EXCLE

需要的部分







之前的代码,测试了两份是正确的,但是第三份就无法提取到


今天一份与昨天某一份对比,发现表格单元格框线被调整过(家长电脑填写时,为了适应文字长度,拉过表格边框)

由于框线调整,导致单元格的(XY)坐标不同,也就不能用同一个坐标索引数字,从多个DOCX填写表的固定单元格内提取需要的内容。

考虑到后续也有可能家长在线编辑Word单元格,有意或无意调整边框……因此,这种“插班生word转长表EXCLE(1)提取单元格内容转入excel”的方式宣告失败。
研究思路
既然不能获取“固定的单元格坐标(XY)信息”,那么我就想获取word内部所有纯文本去除空格,根据起止文字选出需要文字





'''
插班生园园通word转长表EXCLE(只要表格里所有文字,根据起止文字提取中间内容)+循环删除空格
deepseek、阿夏
20260228
'''
import os
from docx import Document # 需要安装 python-docx
# 1. 定义目标文件夹路径
folder_path = r"D:\test\20桌面素材\20260228插班生园园通上传信息提取\00word"
# 2. 筛选文件夹下所有 .docx 文件(排除临时文件 ~$*)
docx_files = []
for fname in os.listdir(folder_path):
fpath = os.path.join(folder_path, fname)
if os.path.isfile(fpath) and fname.lower().endswith(".docx") and not fname.startswith("~$"):
docx_files.append(fpath)
if not docx_files:
raise FileNotFoundError(f"文件夹 {folder_path} 中未找到 DOCX 文件")
print(f"✅ 共找到 {len(docx_files)} 个DOCX文件,开始逐个处理:")
print("-" * 80)
# 核心提取函数(新增支持指定关键词出现次数)
def extract_content(text, start_key, end_key, var_name, occurrence=1):
"""
提取文本中指定次数出现的起始关键词和结束关键词之间的内容
:param text: 待处理的完整文本
:param start_key: 起始关键词(如“族”)
:param end_key: 结束关键词(如“国”)
:param var_name: 变量名(如“Ethnicity”)
:param occurrence: 起始关键词的出现次数(默认1,即第一个)
:return: 提取的内容(失败返回None)
"""
try:
# 找到第N次出现的起始关键词位置
start_idxs = []
start_pos = 0
# 循环查找所有起始关键词的位置
while True:
try:
idx = text.index(start_key, start_pos)
start_idxs.append(idx)
start_pos = idx + len(start_key) # 从下一个位置继续找
except ValueError:
break
# 检查是否有足够的出现次数
if len(start_idxs) < occurrence:
raise ValueError(f"起始关键词‘{start_key}’仅出现{len(start_idxs)}次,不足{occurrence}次")
# 取第occurrence次出现的位置(跳过关键词本身)
start_idx = start_idxs[occurrence - 1] + len(start_key)
# 从该位置后找结束关键词
end_idx = text.index(end_key, start_idx)
# 截取并清理内容
content = text[start_idx:end_idx].strip()
return content
except ValueError as e:
print(f"❌ 提取{var_name}失败:{e}")
return None
# 定义提取配置(IDparent指定取第三个“身份证”)
extract_config = [
("姓名", "性别", "name"), # 姓名
("性别", "曾用名", "sex"), # 性别
("籍贯", "幼", "Hometown"), # 籍贯
("民族", "国别", "Ethnicity"), # 民族
("出生日期", "出生证", "birthday"),# 出生日期
("出生地", "独", "birthplace"), # 出生地
("其他证件号码:", "户口性质", "ID"),# 身份证号
("本区户口需填全", "所属街镇", "PPA"),# 户籍地址
("产证登记日现住地址", "所属", "RA"),# 居住地址
("室所属", "邮编", "NC"), # 居委
("移动电话", "身份证", "parent"), # 监护人
("身份证", "否是", "IDparent", 1), # 监护人ID(第三个“身份证”)
("家庭电话", "健康状况", "phone") # 手机号
]
# 存储所有文件的提取结果(键:文件名,值:提取结果字典)
all_results = {}
# 3. 遍历所有DOCX文件,逐个处理
for file_idx, docx_file in enumerate(docx_files, 1):
print(f"📄 正在处理第 {file_idx}/{len(docx_files)} 个文件:{os.path.basename(docx_file)}")
# 读取当前DOCX文件
try:
doc = Document(docx_file)
except Exception as e:
print(f"❌ 读取文件失败:{e}")
print("-" * 80)
continue
# 检查是否有表格
if not doc.tables:
print("❌ 该文件中没有表格")
print("-" * 80)
continue
# 读取第一个表格的文字,去重、去换行、去空格
table = doc.tables[0]
all_text = []
processed_text = set()
for row in table.rows:
for cell in row.cells:
# 清除换行符和所有空格
cell_text = cell.text.replace("\n", "").replace("\r", "")
cell_text = cell_text.replace(" ", "").replace(" ", "")
# 过滤空内容和重复内容
if cell_text and cell_text not in processed_text:
processed_text.add(cell_text)
all_text.append(cell_text)
final_text = "".join(all_text)
# 打印当前文件的处理后文本(可选,如需精简输出可注释)
print("处理后的完整文本:")
print(final_text[:] + "..." if len(final_text) > 1000 else final_text)
# 提取当前文件的所有信息
current_result = {}
for item in extract_config:
if len(item) == 4:
start_key, end_key, var_name, occurrence = item
else:
start_key, end_key, var_name = item
occurrence = 1
current_result[var_name] = extract_content(final_text, start_key, end_key, var_name, occurrence)
# 保存当前文件的结果
all_results[docx_file] = current_result
# 打印当前文件的提取结果
print("🔍 当前文件提取结果:")
for var_name, value in current_result.items():
print(f" {var_name:10}:{value if value else '未提取到'}")
print("-" * 80)
# 4. 打印所有文件的汇总结果(可选)
print("📊 所有文件提取结果汇总:")
for docx_file, result in all_results.items():
print(f"\n文件:{os.path.basename(docx_file)}")
for var_name, value in result.items():
print(f" {var_name:10}:{value if value else '未提取到'}")

从终端里可以看到,已经提取“表格”范围内的所有文字,并去掉空格

人工提取需要信息的前面几个字,后面几个字(作为切割点)


大部分信息都提取到了

但是也有不正确的地方
1、有3个身份证,所以提取范围从身份证到否是,。
结果显示很长一条(应该就是一位家长的18位身份证号),
分析发现:身份证有3个,它从第1个身份证开始到第1个否是,中间的内容都记录了

改成第2个身份证,稍微短一点

改成第3个身份证,正确

还有一个居住地址NC也有问题
如果索引1,显示长文字

如果索引2,显示“未提取到”

同样方式测试很多插班生word

按照这个提取


户籍地址、居住地址太长,父亲身份证和电话缺失

幼儿身份证号缺失、户籍地址和居住地址太长

信息重复提取

户籍地址、居住地址太长

总之,无法用一个统一的代码中的起止汉字,来提取我想要的中间部分的关键信息。因为部分汉字有多个,如“身份证”、“是否”、“否是”、“产权”、“地址”等
由此可见,通过提取所有汉字,可以获得无空格整段排列的所有内容,但是因为汉字有重复性且表格可能有变化,所以输出文字排列有差异,所以无法根据特定的起止文字选出指定需要的文字。
后续思考
获取表格里面每一行的文字(缩小起止汉字所在的范围)做成列表,提取指定索引里面的文字。