尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

北师大版小学语文课文总目录:从Word到结构化数据的Python实践

北师大版小学语文课文总目录:从Word到结构化数据的Python实践 简介北师大版小学语文课文总目录.doc 是一份系统整理的小学语文教材课文目录文档面向小学语文教师、家长及自学者可用于快速查询各年级课文分布、单元主题及语文天地活动内容为备课、辅导和制定学习计划提供清晰索引。文档共1个doc文件仅119KB左右却完整收录了北师大版小学语文第一册至第四册的课文总目录包含‘上学了’‘字与画’‘学写字’‘数字’‘家’‘字与拼音’‘太阳和月亮’‘大海’‘外面的世界’‘手和脑’‘梦想’‘劳动’‘冬天’‘成长’等第一册单元以及第二册的‘元宵节’‘家园’‘春天’‘植物’‘动物’‘爱护’‘愿望’‘认真’‘车的世界’‘雨’‘星空’‘朋友’‘时间’‘长大’‘快乐’第三册的‘秋天’‘祖国’‘自立’‘好奇’‘勇敢’‘合作’‘书的世界’‘考验’‘水和风’‘诚实’‘画’‘玩具和游戏’‘岁月’第四册的‘好习惯’‘妈妈’‘植树’‘青青的山’‘动脑筋’‘远行’‘体育世界’‘讲信用’‘清清的水’等主题单元并标注了对应课文篇目层级分明便于检索。目前已有64人学习下载是教师梳理教材体系、家长辅导孩子预习复习以及教研人员分析北师大版语文教材编排特点的实用参考。1. 《北师大版小学语文课文总目录.doc》不是一份文档是一套检索系统在教育内容平台接新课标教材数据的排期里最容易被低估的工作不是分词、不是索引而是拿一份《北师大版小学语文课文总目录.doc》去对齐产品侧、教研侧和数据侧的三套字段。第一次接触这套语文资料的人往往以为它是给老师查课文的静态文件但在工程上它是一棵结构松散的目录树一至六年级共 12 册单元少则 2 篇多则 6 篇年级用汉字、学期用上下单元序号有时是数字、有时是汉字标题里还混着“*”和批注。这篇文章不讲一篇篇手动扒目录讲的是把这份目录生成出来、解析掉并让它变成页面导航和数据库都能直接消费的结构化数据适合教育行业内容运营、教研平台后端和想规范化课程元数据的工程师。2. 先把结构立住《北师大版小学语文课文总目录》的数据模型设计一份总目录要长期维护首先要避免一个经典错误直接用课文标题当唯一标识。以《北师大版小学语文课文总目录》的实际情况看“课文”这个颗粒度太粗课文可能包含两首古诗或一篇带说明的短文“语文天地”里还会附带略读文本产品端显示“课”还是“篇”的需求经常打架。因此我一般先做一个四层结构模型册、单元、课、篇目。信息架构的优先级高于 Word 排版因为后面生成 doc、导出 JSON、同步 MySQL 都依赖这棵树是否稳定。2.1 北师大版小学语文“册—单元—课—篇目”的四层关系教材层级和软件实体不是一一对应的先看这棵树长什么样层级数据对象常见取值格式在系统中的职责册book一年级上册至六年级下册共 12 册决定学段导航与课程包边界单元unit单元序号或单元主题名与单元教学目标绑定课lesson序号或“语文天地”等特殊课型决定课表排期篇目piece单个文本条目标题内容 API 的原子信息单元这里最容易忽略的是“课”和“篇目”的分离。比如某册第三课“古诗两首”在页面上是一课实际包含两首独立的诗如果产品只记录“古诗两首”搜索时无法命中单首诗名阅读页也无法精确标记“已读哪一首”。把篇目单独成层后Word 总目录可以继续按“课”展示接口层却可以精确到“篇目”两份产物互不干扰。2.2 目录字段设计从册次到篇目的一张表《北师大版小学语文课文总目录》最终要落成一张宽表字段不宜全照搬教材封面应按检索和导航的最小需求来。我常用的字段集如下字段名类型说明示例book_idtext册次唯一编码g3s1gradeint年级 1-63semesterint0 表示上册1 表示下册1unit_noint单元序号2unit_nametext单元主题名自然与想象lesson_noint课序号3piece_idtext篇目唯一编号g3s1_u2_l3_p1piece_titletext单篇标题登鹳雀楼authortext作者或来源王之涣genretext文体古诗is_readingbool是否略读/拓展阅读falseremarktext备注要求背诵字段顺序就是读出顺序。实际维护中要注意不要把 unit_no 和 lesson_no 设计成“不跳号”因为教材改版后单元内课文可能增删跳号反而能保留历史数据连续编号会带来大量改动。2.3 用 Python 建立最小可运行的数据源有了字段定义下一步是把这个模型变成代码后续的 doc 生成、JSON 导出都由同一份内存数据驱动。from dataclasses import dataclass dataclass class Piece: book_id: str # 册次唯一编码如 g3s1 unit_no: int # 单元序号 lesson_no: int # 课序号 seq: int # 同一课内出现的顺序从 1 开始 piece_title: str # 单篇标题 author: str # 作者或来源 genre: str # 文体如古诗、散文、童话 is_reading: bool False # 是否略读/拓展阅读 pieces [ Piece(g3s1, 1, 1, 1, 我们的学校, 佚名, 散文), Piece(g3s1, 1, 1, 2, 校园的早晨, 罗丹, 诗歌), ]这段代码的作用是让“课文目录”不再躺在 Word 里而是进入可排序、可筛选、可测试的数据结构。参数中最关键的是book_id和piece_id的生成规则前者要保证全公司统一后者用于数据库唯一键一旦发布就不要修改。3. 生成《北师大版小学语文课文总目录.doc》python-docx 模板化输出数据模型落地后生成 Word 就只是渲染问题。但直接写入二进制 .doc 不是一个好方案python-docx 只能生成 docx而标题指名要 .doc这两者存在格式兼容的历史差异。这里要先分清需求是必须交一个能在 Word 97-2003 打开的文件还是只要交付物是“Word 文档”。后者优先输出 docx再由命令转存为 .doc 保底这是教育行业最常见也最稳妥的做法。3.1 doc 与 docx 的真实差异以及为什么用 python-docx.doc 是 OLE 复合文档格式Word 97-2003 使用里面直接存放二进制流解析依赖特定库.docx 是 Open XML 规范本质是一个 ZIP 包Python 生态支持极好python-docx 可以直接读写标题、段落、表格和样式。除非目标系统强制要求 .doc 扩展名否则我建议中间产物一律用 docx最后再一次性转换。pip install python-docx # 将生成的 docx 转为 doc供老版本 Word 或指定系统使用 soffice --headless --convert-to doc 北师大版小学语文课文总目录.docx转换命令中soffice是 LibreOffice 的无头模式入口核心参数--convert-to doc表示输出二进制 Word 格式。需要留意的是LibreOffice 转换后字体可能被替换中文排版可能出现偏差所以转换前要在 python-docx 里把中文字体显式写好。3.2 从数据模型生成 Word标题和课文条目的最小实作这份 Word 的排版逻辑是一级标题写册次二级标题写单元三级标题写课文正文写篇目。这样生成的文件不只是给人看的还能被后续解析脚本识别因为层级关系藏在样式里。from docx import Document from docx.shared import Pt from docx.oxml.ns import qn doc Document() # 设置默认西文字体和中文 eastAsia 字体避免宋体丢失 style doc.styles[Normal] style.font.name Times New Roman style.font.size Pt(12) style.element.rPr.rFonts.set(qn(w:eastAsia), 宋体) doc.add_heading(北师大版小学语文课文总目录, level0) for book, unit_pieces in group_by_book(pieces): doc.add_heading(f第{book.grade}年级{book.semester_name}, level1) for unit, unit_items in group_by_unit(unit_pieces): doc.add_heading(f第{unit}单元, level2) for piece in unit_items: prefix 略读 if piece.is_reading else p doc.add_paragraph() p.add_run(f{prefix}{piece.piece_title}) p.add_run(f {piece.author}).font.size Pt(10) doc.save(北师大版小学语文课文总目录.docx)代码中level参数直接对应 Word 大纲级别这比手动改字号可靠得多。p.add_run创建两个文字片段是为了让作者信息采用小字号显示同时保持段落整体是正文样式。group_by_book和group_by_unit需要自行按book_id和unit_no排序排序顺序直接影响 Word 里的目录顺序务必在生成前完成。3.3 中文字体和缩进在两个 Word 内核下的表现差异生成 doc 后最常见的反馈是“在 WPS 里正常Word 里字体变了”。这不是排版错误而是字体回退机制在起作用。常见问题与对策如下现象原因处理方式宋体变成等线未设置 eastAsia 字体在样式里用 qn(w:eastAsia) 指定中文字体课文标题前出现多余缩进正文段落继承了默认首行缩进显式设置 paragraph_format.first_line_indent Pt(0)转换 doc 后表格线消失LibreOffice 转换时样式映射差异优先转 docx除非必须交付 .doc这里有一个容易被忽略的细节python-docx 的add_paragraph不会自动清空样式里的缩进如果模板基于“正文”样式改过生成的内容就会带上奇怪的首行缩进。我一般在生成后追加一个校验函数遍历所有正文段落把first_line_indent等于None或非零的段落统一修正为Pt(0)或指定值。4. 反向解析与同步把 .doc 总目录变成 JSON 和数据库增量Word 文件不只是给人看的交付物还是内容数据回流的入口。教研老师可能在 Word 里手工改过课文标题运营人员也可能用批注补了备注这些改动最终要回到业务系统。反向解析的思路正好和生成相反读文件、按标题样式分层、还原字段、写入数据库。4.1 .doc 读不进 Python先转换回 docxpython-docx 只能读 docx遇到历史遗留的 .doc 文件要先统一转换。与其写一个 OLE 解析器不如直接用 LibreOffice 批量转换速度和稳定性都够用。mkdir -p converted soffice --headless --convert-to docx --outdir converted 北师大版小学语文课文总目录.doc--outdir指定输出目录避免转换文件覆盖原文件。转换后用 python-docx 打开如果报错先检查文件是否真的是 Word 格式而不是重命名过的 docx 或 RTF 文件。4.2 解析 Word 标题层级还原课文记录解析的关键是依靠样式名而不是文字缩进或字符特征。样式比格式靠谱因为生成端已经把层级写进样式反向解析时读样式名即可还原册、单元、篇目。from docx import Document doc Document(converted/北师大版小学语文课文总目录.docx) rows [] current_grade current_unit for p in doc.paragraphs: text p.text.strip() if not text: continue style_name p.style.name.lower() if style_name.startswith(heading 1): current_grade text elif style_name.startswith(heading 2): current_unit text elif style_name.startswith(heading): # 课文标题归到篇目记录 rows.append({grade: current_grade, unit: current_unit, title: text})这个脚本写得很保守遇到任何非标题段落直接跳过避免把页眉页脚或批注带进数据。解析完成后要检查current_grade和current_unit是否为空为空说明文档样式链断了需要回到生成端修复。4.3 导出 JSON 并用 piece_id 做增量合并解析出的rows只是中间态要做幂等合并必须给每一行生成稳定的piece_id然后写进数据库。增量同步用INSERT ... ON DUPLICATE KEY UPDATE最直接MySQL 和 tidb 都支持。[ { book_id: g3s1, grade: 3, semester: 1, unit_no: 1, lesson_no: 1, piece_id: g3s1_u1_l1_p1, title: 我们的学校, author: 佚名 } ]INSERT INTO chinese_text_catalog (piece_id, book_id, grade, semester, unit_no, lesson_no, seq, title, author, updated_at) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()) ON DUPLICATE KEY UPDATE title VALUES(title), author VALUES(author), updated_at NOW();这里的要点是piece_id一旦生成就不变教材再版时新增课文用新 ID删除的课文保留在历史表。如果直接用标题当唯一键改一个字就会变成两条重复记录。5. 进阶给 Word 目录加跳转书签再回灌 CSV5.1 在课文标题上插入 Word 内部书签总目录文档的一个高频使用场景是教研组开会时点目录跳到正文页。Word 支持书签跳转python-docx 没有直接提供书签 API需要操作底层 XML。from docx.oxml.shared import OxmlElement from docx.oxml.ns import qn def add_bookmark(paragraph, bookmark_id, bookmark_name): start OxmlElement(w:bookmarkStart) start.set(qn(w:id), str(bookmark_id)) start.set(qn(w:name), bookmark_name) end OxmlElement(w:bookmarkEnd) end.set(qn(w:id), str(bookmark_id)) paragraph._p.insert(0, start) paragraph._p.append(end) # 示例给篇目段落加书签 p doc.add_paragraph(我们的学校) add_bookmark(p, 1001, g3s1_u1_l1_p1)插入书签后用户可以在 Word 中按 CtrlG 输入书签名跳转也可以给目录页文本设置超链接指向书签。书签名称直接用piece_id这样和数据库记录一一对应导出文档也不会丢失关联信息。5.2 用 pandas 导出 CSV 供老师维护不是所有同事都习惯在 Word 批注里提意见教研老师通常直接把 Excel 传回来。把解析结果导出成 CSV再用 Excel 打开编辑是一条阻力最小的协作路径。import pandas as pd df pd.DataFrame(rows) df.to_csv(北师大版小学语文课文总目录.csv, indexFalse, encodingutf-8-sig)utf-8-sig是必写参数它会在文件头部写入 BOMExcel 识别 BOM 后中文才不会乱码。字段顺序按之前宽表定义排列老师只改标题、作者等有限列列名保持不变回收后用 pandas 读回继续走合并逻辑。5.3 入库前快速验证重复、缺单元、册次连续性数据回灌前必须跑一轮完整性检查脚本放在 CI 或任务编排里用断言直接拦截异常。assert df[piece_id].is_unique, 发现重复的篇目编号 assert set(df[book_id]) expected_books, 册次不连续 assert df.groupby([book_id, unit_no]).ngroups expected_units, 单元数异常expected_books提前定义为 12 个册次编码expected_units根据各册单元数量动态计算。任何断言失败日志会直接指明是重复编号还是册次缺失此时不要覆盖线上表先比对 diff 文件。这套验证配合前面的 JSON 导出可以让《北师大版小学语文课文总目录.doc》从静态文档变成稳定的数据管线出口。本文还有配套的精品资源点击获取
返回列表