简介:这份PDF汇总了最新人教版小学语文1至6年级全部古诗词与日积月累内容,面向小学语文教师、家长及需要系统梳理小学阶段古诗文的学习者,可解决逐册翻找、版本不一、复习无纲的问题。资源包共1个PDF文件,约72KB,按年级分册编排,涵盖一年级《静夜思》《咏鹅》至六年级《石灰吟》《竹石》等经典篇目,并附二年级日积月累、节气歌、成语与名言警句等积累内容。目前已有230人学习下载。读者可借此快速建立小学六年古诗文知识框架,按册检索原文,用于备课、晨读、期末复习与亲子共读,也能对照各年级篇目查漏补缺,把握从唐诗宋词到元曲、明清诗歌的编排脉络,是一份轻量而实用的古诗文学习索引。
1. 从一份 PDF 汇总说起:古诗词数据化到底难在哪
很多做教育类工具、题库系统或家长端小程序的开发者,都遇到过同一个需求:把小学阶段散落在各册教材里的古诗词和日积月累整理成结构化数据。人教版小学语文一到六年级,古诗词分布在课文、语文园地、日积月累等多个位置,格式不统一,有的带注释,有的只有正文,有的还夹着作者朝代。手工整理一份 PDF 汇总看似简单,真正落到代码里就会发现:断句、标点、作者归属、年级册次映射,每一项都能让解析脚本翻车。
这份「最新人教版小学语文古诗词和日积月累全汇总(1-6年级).pdf」的价值不在于 PDF 本身,而在于它是一份相对完整的语料底本。把它变成可查询、可检索、可导入数据库的结构化数据,才是工程上真正要解决的问题。适合谁看:做 K12 教育产品的后端和前端、需要批量导入诗词数据的运营工具开发者,以及想给孩子做背诵打卡小程序的独立开发者。
2. 解析 PDF 前的数据建模与文本清洗
2.1 先定 schema,再动手解析
拿到 PDF 不要急着写解析代码。先想清楚最终要存成什么结构。古诗词和日积月累两类内容字段不同,建议分开建模。
| 字段名 | 类型 | 说明 | 是否必填 |
|---|---|---|---|
| id | int | 主键 | 是 |
| grade | int | 年级 1-6 | 是 |
| volume | varchar | 上册/下册 | 是 |
| category | varchar | 古诗/词/日积月累 | 是 |
| title | varchar | 篇名 | 是 |
| author | varchar | 作者,日积月累可为空 | 否 |
| dynasty | varchar | 朝代 | 否 |
| content | text | 正文,换行用 \n | 是 |
| source | varchar | 出处,如语文园地一 | 否 |
这个 schema 的关键决策是:把「日积月累」和「古诗词」用 category 区分,而不是建两张表。原因是查询场景里经常要「按年级拉全部背诵内容」,一张表一次查询就够,避免 union。content 字段保留换行符,前端渲染时再决定是分行还是连排。
2.2 用 pdfplumber 抽取原始文本
PDF 解析工具里,pdfplumber 对中文排版的支持比较稳,能拿到每个字符的坐标,方便后续按位置切分。先装依赖再抽文本。
# 安装:pip install pdfplumber import pdfplumber def extract_raw_text(pdf_path): pages_text = [] with pdfplumber.open(pdf_path) as pdf: for i, page in enumerate(pdf.pages): # layout=True 保留原始空格布局,便于后续按列切分 text = page.extract_text(layout=True) if text: pages_text.append(text) return "\n".join(pages_text) raw = extract_raw_text("古诗词汇总.pdf") print(raw[:800]) # 先看前 800 字,确认编码和排版逻辑说明:extract_text(layout=True)会尽量还原 PDF 里的空格和缩进,这对后面判断「标题行」和「正文行」很关键。参数上,如果 PDF 是扫描件而非文字版,pdfplumber 抽出来是空的,这种情况得先走 OCR,不在本文讨论范围。抽完先打印前几百字,确认没有乱码、没有把两列内容串行。
2.3 清洗规则:标点、空格、页码
原始文本里通常混着页码、页眉、多余空格。清洗要按优先级来,先删干扰行,再统一标点。
import re def clean_text(text): lines = text.split("\n") cleaned = [] for line in lines: s = line.strip() # 跳过纯页码行和页眉 if re.fullmatch(r"\d+", s): continue if "古诗词" in s and "汇总" in s and len(s) < 20: continue # 全角空格转半角,多个空格压成一个 s = s.replace("\u3000", " ") s = re.sub(r" {2,}", " ", s) cleaned.append(s) return "\n".join(cleaned)逻辑说明:页码行用re.fullmatch(r"\d+")精确匹配,避免误删正文里的数字。页眉判断用关键词加长度双重条件,防止把含「古诗词」的正文标题误删。标点统一这步先不做,因为中文标点本身要保留,只处理空格。
提示:清洗规则一定要在完整文本上跑一遍再抽查,不要只看前几页。很多 PDF 前几页排版规整,后面册次格式突变。
3. 按年级册次切分并结构化入库
3.1 用正则锚点定位年级和篇目
清洗后的文本需要按「年级—册次—篇目」三级切分。常见做法是用正则找锚点,比如「一年级上册」「二年级下册」这类字样作为分册标记,篇目则靠「标题 + 作者 + 正文」的模式识别。
import re GRADE_PATTERN = re.compile(r"([一二三四五六])年级(上|下)册") # 匹配「《静夜思》 唐 李白」这类标题行 TITLE_PATTERN = re.compile(r"《(.+?)》\s*([唐宋元明清]?)\s*([\u4e00-\u9fa5]{2,4})?") def split_by_grade(text): result = {} current_grade = None for line in text.split("\n"): m = GRADE_PATTERN.search(line) if m: current_grade = f"{m.group(1)}年级{m.group(2)}册" result.setdefault(current_grade, []) continue if current_grade and line: result[current_grade].append(line) return result逻辑说明:GRADE_PATTERN用中文数字匹配年级,因为教材原文一般写「一年级」而不是「1年级」。TITLE_PATTERN里作者部分设为可选,因为日积月累条目往往没有作者。切分完得到的是「册次 -> 行列表」的字典,下一步再逐行判断是标题还是正文。
3.2 标题与正文的判定逻辑
标题行和正文行的区分是解析成败的关键。经验规则:含书名号的行优先当标题;不含书名号但符合「短行 + 后面跟长行」的,可能是日积月累的题目。
def parse_entries(lines): entries = [] i = 0 while i < len(lines): line = lines[i] m = TITLE_PATTERN.search(line) if m: title = m.group(1) dynasty = m.group(2) or "" author = m.group(3) or "" # 向下收集正文,直到遇到下一个标题或空行块 body = [] j = i + 1 while j < len(lines) and not TITLE_PATTERN.search(lines[j]): if lines[j].strip(): body.append(lines[j].strip()) j += 1 entries.append({ "title": title, "dynasty": dynasty, "author": author, "content": "\n".join(body) }) i = j else: i += 1 return entries逻辑说明:内层 while 负责收集正文,遇到下一个书名号标题就停。这里有个坑:有些篇目的正文里也会出现书名号,比如注释里引用其他诗。稳妥做法是给正文收集加一个行数上限,比如最多 20 行,超过就强制断开并打日志人工复核。
3.3 写入 SQLite 并建索引
结构化数据先落 SQLite,方便本地验证,后续再迁 MySQL 或 PostgreSQL。
import sqlite3 def save_to_db(entries, grade, volume, db_path="poems.db"): conn = sqlite3.connect(db_path) cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS poems ( id INTEGER PRIMARY KEY AUTOINCREMENT, grade INTEGER, volume TEXT, category TEXT, title TEXT, author TEXT, dynasty TEXT, content TEXT, source TEXT ) """) for e in entries: cur.execute( "INSERT INTO poems (grade, volume, category, title, author, dynasty, content) " "VALUES (?, ?, ?, ?, ?, ?, ?)", (grade, volume, "古诗", e["title"], e["author"], e["dynasty"], e["content"]) ) conn.commit() conn.close()逻辑说明:grade 存整数便于范围查询,volume 存「上册/下册」字符串。category 这里先写死「古诗」,日积月累的条目在解析时用另一套规则标记。建表用IF NOT EXISTS保证脚本可重复跑。数据量不大,单条 insert 足够,几千条以内不用考虑批量优化。
注意:入库前一定要去重。同一首诗可能在不同册次重复出现(比如作为复习内容),用 title + grade 做唯一性校验,避免查询时出重复行。
4. 查询、校验与常见解析坑
4.1 按年级和关键词查询的 SQL 写法
数据入库后,最常见的查询是「某年级全部内容」和「按诗句关键词搜」。前者简单,后者需要模糊匹配。
-- 查三年级全部背诵内容,按册次和篇名排序 SELECT grade, volume, title, author, content FROM poems WHERE grade = 3 ORDER BY volume, id; -- 按诗句关键词搜索,比如找含「明月」的诗 SELECT title, author, content FROM poems WHERE content LIKE '%明月%' OR title LIKE '%明月%';逻辑说明:第一条查询走 grade 索引,如果数据量大可以给 grade 建索引。第二条 LIKE 前后都带通配符,无法走索引,数据量上万后会慢。优化方向是用全文检索,SQLite 可以开 FTS5,把 title 和 content 建虚拟表。
-- SQLite FTS5 全文检索 CREATE VIRTUAL TABLE poems_fts USING fts5(title, content, content='poems', content_rowid='id'); INSERT INTO poems_fts(rowid, title, content) SELECT id, title, content FROM poems; -- 查询 SELECT * FROM poems_fts WHERE poems_fts MATCH '明月';逻辑说明:FTS5 对中文分词默认按字切,搜「明月」能命中,但搜「明月光」这种跨词组合需要配置分词器。小数据量下 LIKE 够用,别过早优化。
4.2 校验解析结果的三个检查点
解析完不能直接上线,至少做三项校验。第一,统计每个年级的篇目数,和教材实际数量对比,偏差超过 10% 就说明切分有问题。第二,抽查 content 字段有没有混入页码或页眉。第三,检查 author 字段有没有把正文首句误当作者。
def validate(db_path="poems.db"): conn = sqlite3.connect(db_path) cur = conn.cursor() # 检查点一:各年级篇目数 cur.execute("SELECT grade, COUNT(*) FROM poems GROUP BY grade") for row in cur.fetchall(): print(f"年级 {row[0]}: {row[1]} 篇") # 检查点二:正文过短的条目 cur.execute("SELECT title, LENGTH(content) FROM poems WHERE LENGTH(content) < 10") for row in cur.fetchall(): print(f"疑似异常: {row[0]} 正文长度 {row[1]}") conn.close()逻辑说明:正文长度小于 10 的条目大概率是解析断了,需要人工看。作者字段的校验可以加一条规则:如果 author 长度超过 4 个汉字,基本可以判定是误抓,因为古人名字很少超过四字。
4.3 几个高频翻车点
第一个坑是繁简混排。部分 PDF 底本用了繁体字,直接入库会导致搜索「明月」搜不到「明月」的繁体写法。清洗阶段统一转简体,用 opencc 或简单的映射表。
第二个坑是标点全半角混用。正文里「,」和「,」混着出现,前端展示会很难看。统一转全角中文标点。
第三个坑是日积月累里的谚语、成语被当成古诗解析。这类内容没有书名号,也没有作者,用 TITLE_PATTERN 匹配不到,会被漏掉。解决办法是给日积月累单独写一套规则:以「日积月累」字样为锚点,向下收集到下一个年级标记为止。
def parse_riji(text): # 以「日积月累」为起点,收集后续非空行 blocks = re.split(r"日积月累", text) items = [] for block in blocks[1:]: lines = [l.strip() for l in block.split("\n") if l.strip()] if lines: items.append("\n".join(lines[:10])) # 最多取 10 行 return items逻辑说明:split 后第一段是「日积月累」之前的内容,丢弃。每段最多取 10 行,防止把下一节内容吞进来。这类启发式规则一定要配合人工抽查,不能全自动跑完就信。
5. 把汇总数据接进小程序或题库的进阶技巧
数据整理完,真正的价值在于用起来。如果目标是做背诵打卡小程序,最实用的技巧是给每首诗生成一个「首字提示」字段,用户背不出来时点一下显示每句首字。这个字段可以在入库时用脚本批量生成,不用前端实时算。
def make_hint(content): # 按标点断句,取每句首字 sentences = re.split(r"[,。?!;]", content) return "".join(s[0] for s in sentences if s) # 批量更新 conn = sqlite3.connect("poems.db") cur = conn.cursor() cur.execute("ALTER TABLE poems ADD COLUMN hint TEXT") cur.execute("SELECT id, content FROM poems") for pid, content in cur.fetchall(): cur.execute("UPDATE poems SET hint = ? WHERE id = ?", (make_hint(content), pid)) conn.commit()逻辑说明:re.split用中文标点断句,取每句第一个字拼成提示串。注意 content 里如果有换行,split 后可能产生空串,用if s过滤。这个 hint 字段让前端逻辑极简,直接展示即可。
另一个进阶用法是导出成 JSON 供前端静态加载,避免每次查询都打数据库。导出时按年级分文件,小程序按需加载。
import json def export_by_grade(db_path="poems.db", out_dir="./data"): conn = sqlite3.connect(db_path) cur = conn.cursor() for grade in range(1, 7): cur.execute( "SELECT title, author, dynasty, content, hint FROM poems WHERE grade = ?", (grade,) ) rows = [dict(zip(["title", "author", "dynasty", "content", "hint"], r)) for r in cur.fetchall()] with open(f"{out_dir}/grade_{grade}.json", "w", encoding="utf-8") as f: json.dump(rows, f, ensure_ascii=False, indent=2) conn.close()逻辑说明:按年级拆文件,单个文件体积小,小程序分包加载友好。ensure_ascii=False保证中文正常显示。导出后建议用json.load回读一次验证格式,避免写入时编码出错导致前端解析失败。
最后一个技巧关于数据更新:教材偶尔会有微调,汇总数据要能增量更新而不是全量重跑。给每条记录加一个version字段,新版本解析时对比 title + grade,只更新 content 变化的条目。这样每次教材调整只需要跑一次 diff,人工复核量从几千条降到几条。
本文还有配套的精品资源,点击获取