批改作业小工具(一)-read report
期末 ,总是疲于应付各类作业报告批改,搞个小工具,让它帮我一把~~~~
(格式)
读取报告:
import docx
from docx.table import Tabledef extract_experiment_reports(doc_path):"""提取文档中所有实验报告的关键内容"""doc = docx.Document(doc_path)reports = [] # 存储所有实验报告for table in doc.tables:report = {"实验目的及要求": "","实验使用的主要设备及要求": "","实验操作内容及步骤": "","实验结果与分析总结": "","指导教师评阅意见和评分": ""}current_section = None # 当前处理的章节# 遍历表格中的所有单元格for row in table.rows:for cell in row.cells:# 处理单元格文本,去除多余空行和空格text = cell.text.strip()if not text:continue# 识别章节标题if "一、实验目的及要求" in text:current_section = "实验目的及要求"# 提取标题后的内容content = text.split("一、实验目的及要求", 1)[1].strip()report[current_section] = contentelif "二、实验使用的主要设备(含软件系统)及要求" in text:current_section = "实验使用的主要设备及要求"content = text.split("二、实验使用的主要设备(含软件系统)及要求", 1)[1].strip()report[current_section] = contentelif "三、实验操作(制作)内容及步骤" in text:current_section = "实验操作内容及步骤"content = text.split("三、实验操作(制作)内容及步骤", 1)[1].strip()report[current_section] = contentelif "四、实验结果与分析总结" in text:current_section = "实验结果与分析总结"content = text.split("四、实验结果与分析总结", 1)[1].strip()report[current_section] = contentelif "五、指导教师评阅意见和评分" in text:current_section = "指导教师评阅意见和评分"content = text.split("五、指导教师评阅意见和评分", 1)[1].strip()report[current_section] = content# 累加章节内容(处理跨单元格的文本)elif current_section:report[current_section] += "\n" + text# 过滤无效报告(至少包含一个有效章节)if any(report.values()):reports.append(report)return reportsdef print_reports(reports):"""打印所有提取的实验报告内容"""for i, report in enumerate(reports, 1):print(f"===== 实验报告 {i} =====")for section, content in report.items():print(f"\n【{section}】")# 处理空内容print(content if content else "无内容")print("\n" + "="*50 + "\n")if __name__ == "__main__":# 替换为实际文档路径doc_path = "report/华为HCIA-GaussDB应用开发22计科本六21106080900204纪容超.docx"try:reports = extract_experiment_reports(doc_path)print(f"成功提取 {len(reports)} 个实验报告\n")print_reports(reports)except Exception as e:print(f"提取失败:{str(e)}")
文档内容提取器
这段代码其实就是个 "文档内容提取器",专门把 Word 里的实验报告内容按类别挑出来。
第一部分:准备工作
import docx |
这行就像请了个 "助手",这个助手叫docx,专门会读 Word 文档,没有它程序就不认识 Word 文件。
第二部分:提取内容的函数(extract_experiment_reports)
这个函数就像一个 "扫描仪",负责把文档里的实验报告一页页扫出来:
- 先打开文档
doc = docx.Document(doc_path) |
相当于你双击打开了 Word 文件,doc_path就是你的文档存放位置。
- 准备一个 "文件夹" 放报告
reports = [] # 存储所有实验报告 |
就像你准备了一个空文件夹,等下要把扫出来的报告都放这里。
- 开始扫描表格
for table in doc.tables: |
程序知道每个实验报告都是一个表格,所以它会一个表格一个表格地看。
- 给每个报告建 5 个 "小盒子"
report = { "实验目的及要求": "", "实验使用的主要设备及要求": "", "实验操作内容及步骤": "", "实验结果与分析总结": "", "指导教师评阅意见和评分": "" } |
每个实验报告都有这 5 部分,程序先准备好 5 个空盒子,等着装内容。
- 仔细读表格里的字
for row in table.rows: for cell in row.cells: |
表格是一行一行、一格一格的,程序会逐个格子读里面的文字。
- 识别标题,把内容放进对应盒子
if "一、实验目的及要求" in text: current_section = "实验目的及要求" content = text.split("一、实验目的及要求", 1)[1].strip() report[current_section] = content |
这部分是核心:当程序读到 "一、实验目的及要求" 时,就知道后面的内容要放进 "实验目的及要求" 这个盒子里。其他几个标题也是同样的道理。
- 处理跨格子的内容
elif current_section: report[current_section] += "\n" + text |
如果一段内容太长,分成了好几个格子写,程序会自动把它们拼在一起(比如实验步骤可能分了好几格,程序会合并成完整的步骤)。
第三部分:打印内容的函数(print_reports)
这个函数就像一个 "播音员",把提取出来的内容一条一条念给你听:
for i, report in enumerate(reports, 1): print(f"===== 实验报告 {i} =====") |
先报序号,告诉你这是第几个实验报告,然后依次念出每个盒子里的内容。
第四部分:主程序
if __name__ == "__main__": doc_path = "report/你的文档名.docx" reports = extract_experiment_reports(doc_path) print_reports(reports) |
这部分是 "总指挥":告诉你的文档在哪里,然后指挥 "扫描仪" 去扫文档,最后让 "播音员" 把结果念出来。如果中间出错了(比如文档找不到),还会告诉你哪里错了。
总结一下
整个程序就像一个流水线:
- 先请个助手(docx)帮忙读 Word
- 扫描仪(extract_experiment_reports)把每个实验报告的 5 部分内容分别装进 5 个盒子
- 播音员(print_reports)把盒子里的内容按顺序念出来
不管文档里有多少个实验报告,程序都会一个一个处理,最后整整齐齐地展示在屏幕上,不用你手动去复制粘贴了~
跨单元格文本处理原理
核心原理:用一个 “标记” 记住当前正在读哪一部分
- 先设一个 “当前章节标记”(current_section)
一开始这个标记是空的,相当于 “还没开始读任何章节”。
- 遇到章节标题时,更新标记
当程序读到 “一、实验目的及要求” 时,就把标记改成 “实验目的及要求”,相当于告诉自己:“接下来我要读的都是‘实验目的’这部分内容了”。
- 没遇到新标题时,就把内容加到当前章节里
只要这个标记不是空的(说明正在读某一章节),后面读到的内容就自动归到这个章节里,用+=拼接起来,再加上换行符\n让内容排版整齐。
- 遇到新标题时,标记会被替换
比如读到 “二、实验设备” 时,标记就会换成 “实验使用的主要设备及要求”,后面的内容就开始归到这部分了。
举个生活中的例子
这就像你用笔记本记笔记:
- 先在笔记本上写 “一、实验目的”(相当于设置了 current_section)
- 接下来写的内容都默认是这一部分的,哪怕换了一页(相当于跨单元格),你也会接着写在这一部分下面
- 直到你写下 “二、实验设备”(相当于更新了 current_section),之后的内容才会记到新的部分里
这样就保证了:不管一段内容被拆成多少个表格单元格(甚至多少页),只要没遇到新的章节标题,就会被当作同一部分内容拼在一起,不会零散错乱。
拼接表格单元格内容
# 累加章节内容(处理跨单元格的文本) elif current_section:report[current_section] += "\n" + text
这句话的意思是:把同一章节中跨多个表格单元格的内容拼接起来,让内容保持完整。
举个具体例子你就明白了:
假设 "实验步骤" 内容太长,被分成了 3 个表格单元格来写:
- 第一个单元格:" 打开数据库软件"
- 第二个单元格:" 输入账号密码登录"
- 第三个单元格:" 执行查询命令"
程序的处理过程是:
- 当读到第一个单元格里的 "三、实验操作内容及步骤" 时,会标记current_section = "实验操作内容及步骤",并把后面的 " 打开数据库软件" 放进对应盒子里。
- 读到第二个单元格时,因为current_section已经是 "实验操作内容及步骤" 了,就会执行report[current_section] += "\n" + text,相当于:
盒子里的内容 = 原来的内容 + 换行 + 新内容
变成:"1. 打开数据库软件 \n2. 输入账号密码登录"
- 读到第三个单元格时,同样执行拼接,最后盒子里的内容会变成:
"1. 打开数据库软件 \n2. 输入账号密码登录 \n3. 执行查询命令"
这样处理后,原本分散在多个格子里的同一段内容,就会被拼接成完整的一段,显示的时候也会换行分隔,看起来更清晰。
简单说,就是解决了 "同一章节内容被拆分到多个表格格子里" 的问题,保证你看到的是一整段完整内容,而不是零散的片段。