chinese-poetry开源项目:构建中华古典诗词结构化数据库的实践指南

chinese-poetry开源项目:构建中华古典诗词结构化数据库的实践指南 简介这是一份面向中文自然语言处理、古诗文研究与教育应用开发者的开源古典诗词数据库资源旨在解决传统纸质文集获取门槛高、数字化程度低、结构化难复用等问题。资源以JSON格式组织共2000个文件包含1978个结构化诗词数据文件按朝代、作者、体裁分片存储、16个说明文档含数据规范与使用指南、4个Python/JS工具脚本支持数据加载与简单查询及1个元信息文本整体压缩包大小为91.18MB便于集成至Web服务、移动端或AI训练流程。已有811人学习下载实际数据覆盖5.5万首唐诗、26万首宋诗、2.1万首宋词及大量元曲、诗话等文献诗人逾1.4万名词人超1500名所有条目均标注作者、朝代、标题、正文与出处字段且目录按朝代—作者—作品三级逻辑划分支持快速定位与批量解析。1. 项目概述一个开源的古诗词数据宝库如果你对中华古诗词感兴趣无论是想开发一个诗词小程序、做一个诗词学习网站还是单纯想用程序分析一下唐诗宋词的用词规律那你大概率绕不开一个名字chinese-poetry。这不是一个商业产品而是一个托管在GitHub上的开源项目但它所做的事情却为无数开发者、研究者和爱好者打开了一扇通往古典文学数据化的大门。简单来说chinese-poetry是一个最完整、最规范的中华古典诗歌词、曲、赋数据库它把散落在古籍中的文字变成了结构清晰、格式统一的JSON和SQL文件。我第一次接触这个项目是在几年前想做一个“每日一诗”的桌面插件。当时到处找数据要么格式混乱要么残缺不全直到发现了它。它的价值在于它不仅仅是一个数据“搬运工”。项目维护者投入了大量精力进行数据清洗、校对和结构化。比如一首诗在这里不仅仅是一段文字它被拆解成了标题、作者、朝代、内容、标签、注释等多个字段并且所有数据都采用了统一的编码UTF-8和格式。这意味着你拿到手的数据是“干净”的可以直接导入数据库或用于分析省去了最令人头疼的数据预处理环节。这个项目适合谁呢首先是开发者无论是做移动应用、网站还是数据分析这都是一个现成的、高质量的数据源。其次是教育工作者和研究者可以基于这些结构化数据进行文学研究或开发教学工具。最后即便是普通的诗词爱好者也能通过这个数据库以更数字化的方式探索诗词海洋。接下来我们就深入这个宝库的内部看看它的设计思路、核心内容以及如何真正把它用起来。2. 项目架构与数据源解析2.1 整体设计思路从古籍到结构化数据chinese-poetry项目的核心目标非常明确将非结构化的古典诗文文本转化为机器可读、易于查询和分析的结构化数据。这个目标听起来简单但实现起来涉及文献学、计算机编码和数据库设计等多个领域的交叉。项目的设计思路可以概括为“收集-整理-校验-输出”四个步骤。首先数据收集。项目的数据源主要来自公共领域的古籍数字化成果例如《全唐诗》、《全宋词》等权威汇编的电子版本。这里有一个关键点项目优先选择那些版权已过期或属于公共领域的版本确保了数据的开源合法性。它并不是简单地从某个网站抓取而是综合多个来源进行比对这为数据的准确性打下了基础。其次数据整理与结构化。这是项目的精髓所在。原始的古籍文本通常是连续的没有明确的字段分隔。项目维护者需要定义一套数据模型。我们来看看一首诗在数据库中是如何被建模的title: 诗题。处理时需注意异体字和避讳字的统一如“峯”与“峰”。author: 作者。关联到独立的作者数据库包含作者生平、朝代信息。paragraphs: 诗句内容。这是一个数组每一联或每一句作为一个元素完美保留了诗歌的段落结构。例如一首绝句的paragraphs字段可能是[白日依山尽, 黄河入海流, 欲穷千里目, 更上一层楼]。strains: 平仄信息。这对于研究诗词格律至关重要是高级结构化数据的体现。notes: 注释。从原典中提取的注解。tags: 标签。如“写景”、“抒情”、“山水”等方便内容分类和检索。这种结构化的好处是巨大的。开发者可以根据author字段查询某个诗人的所有作品根据tags筛选特定主题的诗或者分析paragraphs字段中词语的出现频率。2.2 数据组织方式文件与数据库项目提供了两种主要的数据组织形式以适应不同的使用场景。1. JSON文件格式这是最常用、最灵活的数据格式。数据按类别存放在不同的.json文件中。poet.tang.json,poet.song.json: 分别存储唐、宋诗人的基本信息。poetry.tang.json,poetry.song.json: 分别存储唐、宋的诗歌数据。每个JSON对象对应一首诗包含上述的各个字段。还有ci(词)、lunyu(论语) 等分类。使用JSON格式的优势在于轻量、易读且与现代Web开发栈JavaScript/Python无缝集成。你可以直接用import或require加载数据无需数据库服务。2. SQL数据库文件为了方便需要复杂查询和事务操作的应用项目也提供了SQLite数据库文件通常是.sqlite或.db格式。这个数据库已经建好了规范的表结构例如poetry、author、dynasty等表并建立了外键关联。对于想要快速搭建一个具备搜索、筛选功能的诗词网站的后端开发者来说直接使用这个SQL文件初始化数据库可以节省大量建表和数据导入的时间。注意在使用SQL文件前务必检查数据库的字符集是否为UTF-8以确保中文不会出现乱码。同时由于数据量可能很大全唐诗就有数万首在导入到MySQL或PostgreSQL等数据库时可能需要分批操作并注意调整数据库的配置参数如max_allowed_packet。2.3 数据质量与校验机制开源数据项目的生命线在于质量。chinese-poetry在这方面做了不少工作但作为使用者我们也需要了解其局限性和自查方法。内置的校验格式校验通过JSON Schema或脚本检查数据文件的格式是否符合预定规范确保没有缺失的必填字段或错误的字段类型。基础逻辑校验例如检查一首诗的朝代是否与作者的活跃朝代相符虽然古代诗人可能跨朝代但大的矛盾可以检出。重复项检测通过标题、作者和诗句内容的组合哈希来识别和标记可能重复录入的诗歌。使用者需要关注的方面文本准确性尽管经过校对但难免存在个别错别字或标点差异。对于学术精度要求极高的场景建议以权威纸质出版物进行最终核对。作者归属部分诗词存在作者争议如某些佚名诗或归属多人的诗数据库通常采用一种主流说法使用时需注意。数据完整性是否收录了所有你想要的诗词例如一些非常冷门的诗人或作品可能缺失。项目一直在更新但不可能百分百完备。实操心得在将数据投入生产环境前我习惯自己写一个小脚本做一次“健康检查”。比如随机抽样几百条数据打印出来人工快速浏览或者统计一下各朝代诗歌的数量分布看看是否符合历史常识。这能帮你快速建立对数据集的信任感。3. 核心数据内容详解3.1 诗歌诗、词、曲数据解析这是数据库的核心部分。我们以一首唐诗为例深入看看一个JSON对象里究竟有什么。{ id: 5f8790b0a4b7b3b3b3b3b3b3, title: 静夜思, author: 李白, dynasty: 唐, content: 床前明月光疑是地上霜。举头望明月低头思故乡。, paragraphs: [ 床前明月光, 疑是地上霜。, 举头望明月, 低头思故乡。 ], notes: [此诗写静夜思乡之情。], tags: [思乡, 月亮, 唐诗三百首], rhythmic: 五言绝句 }id:唯一标识符。通常是无意义的UUID或自增ID用于数据库关联。contentvsparagraphs:这是两个容易混淆的字段。content是诗歌的完整文本是一个字符串。而paragraphs是一个数组将诗歌按句拆分。在大多数分析场景下使用paragraphs字段更为方便因为你可以直接遍历每一句进行处理而无需自己用正则表达式去拆分content。tags标签这个字段极具价值。它相当于给每首诗打上了关键词。你可以利用它实现“主题阅读”。例如找出所有带有“山水”标签的宋诗或者找出同时带有“秋天”和“悲愁”标签的诗。标签的准确性直接影响检索效果。rhythmic体裁标明是五言绝句、七言律诗、词牌名如“水调歌头”等。这对于诗词格律研究和分类展示非常重要。对于词和曲数据结构类似但会有额外字段。例如词会有cipai词牌名字段曲可能会有qupai曲牌名。在paragraphs的处理上词会按阕片进行更细致的划分。3.2 作者与朝代信息诗人信息通常存放在独立的poet.*.json文件中。一个作者对象可能包含name: 姓名。id: 与诗歌数据关联的ID。dynasty: 所属朝代。desc: 生平简介。birth_year,death_year: 生卒年如果确切可知。关联查询的实践在实际应用中我们很少单独使用作者数据。通常的做法是在加载诗歌数据后根据诗歌中的author字段存储的是作者ID或姓名去作者数据库中查找详细信息然后在界面上展示“李白唐”。在SQL数据库版本中这通过一个简单的JOIN查询即可完成。朝代信息有时会单独作为一个维度表包含朝代名称、起止年份、简介等用于更精细的筛选和历史脉络分析。3.3 其他扩展数据经、赋、元曲等chinese-poetry的野心不止于唐宋诗词。项目还逐步收录了更广泛的中文古典文献《论语》等儒家经典数据被拆分成独立的章节和句子并带有注释可用于经典名句查询或学习应用。《诗经》作为中国诗歌的源头其收录具有特殊意义字段中会包含“风”、“雅”、“颂”的分类以及具体的篇目名。元曲包括散曲和剧曲选段数据结构上会体现曲牌和宫调信息。古典小说如《红楼梦》中的诗词这部分数据关联了具体回目和人物对于红学研究或专题应用很有帮助。这些扩展数据使得项目的应用场景从单纯的诗词欣赏拓宽到了整个中国古典文学与文化领域。4. 实战应用如何获取与使用数据4.1 数据获取与本地部署最直接的方式是访问项目的GitHub仓库克隆或下载整个项目到本地。# 克隆仓库 git clone https://github.com/chinese-poetry/chinese-poetry.git cd chinese-poetry # 或者如果你只需要数据JSON文件可以直接下载数据目录的压缩包如果提供。项目目录结构通常非常清晰chinese-poetry/ ├── data/ # 核心数据目录 │ ├── poetry/ # 诗歌JSON文件 │ ├── ci/ # 词JSON文件 │ ├── authors/ # 作者JSON文件 │ └── ... # 其他分类 ├── database/ # SQL数据库文件 └── ... # 可能包含校验脚本、文档等对于JSON数据的使用以Python为例import json import os # 1. 加载唐诗数据 with open(os.path.join(data, poetry, poetry.tang.json), r, encodingutf-8) as f: tang_poems json.load(f) # tang_poems 是一个包含数万个字典的列表 print(f共加载 {len(tang_poems)} 首唐诗。) print(第一首诗, tang_poems[0][title], -, tang_poems[0][author]) # 2. 简单查询查找李白的诗 li_bai_poems [poem for poem in tang_poems if poem.get(author) 李白] print(f找到 {len(li_bai_poems)} 首李白的诗。) # 3. 关键词搜索在诗句中寻找包含‘明月’的诗 mingyue_poems [] for poem in tang_poems: # 遍历诗句数组进行搜索 for line in poem.get(paragraphs, []): if 明月 in line: mingyue_poems.append(poem) break # 找到一首就跳出内层循环 print(f找到 {len(mingyue_poems)} 首包含‘明月’的唐诗。)对于SQL数据的使用如果你拿到的是.sqlite文件可以使用任何支持SQLite的工具或库来操作。import sqlite3 # 连接到SQLite数据库 conn sqlite3.connect(chinese-poetry.db) cursor conn.cursor() # 执行查询查询宋代词人辛弃疾的词作按标题排序 cursor.execute( SELECT p.title, p.content FROM poetry p JOIN author a ON p.author_id a.id WHERE a.name ? AND p.dynasty ? ORDER BY p.title , (辛弃疾, 宋)) results cursor.fetchall() for title, content in results[:5]: # 打印前5首 print(f《{title}》\n{content}\n) conn.close()4.2 集成到Web应用以Flask为例假设我们要构建一个简单的诗词查询网站。步骤1准备数据将poetry.tang.json导入到一个SQLite或更强大的数据库如PostgreSQL中。这里为了简化我们演示直接使用JSON文件作为“数据库”。步骤2后端APIapp.pyfrom flask import Flask, request, jsonify import json app Flask(__name__) # 启动时加载数据生产环境应考虑缓存或使用真实数据库 with open(data/poetry/poetry.tang.json, r, encodingutf-8) as f: ALL_POEMS json.load(f) app.route(/api/poetry/search) def search_poetry(): 根据作者或关键词搜索诗歌 author request.args.get(author, ).strip() keyword request.args.get(keyword, ).strip() results [] for poem in ALL_POEMS: match True if author and poem.get(author) ! author: match False if keyword and match: # 在标题和诗句中搜索关键词 content_match keyword in poem.get(title, ) or any(keyword in line for line in poem.get(paragraphs, [])) if not content_match: match False if match: # 返回精简信息避免传输过大 results.append({ id: poem.get(id), title: poem.get(title), author: poem.get(author), dynasty: poem.get(dynasty), preview: .join(poem.get(paragraphs, [])[:2]) ... # 预览前两句 }) return jsonify({count: len(results), poems: results[:50]}) # 限制返回数量 app.route(/api/poetry/poem_id) def get_poem_detail(poem_id): 根据ID获取诗歌详情 for poem in ALL_POEMS: if poem.get(id) poem_id: return jsonify(poem) return jsonify({error: Not found}), 404 if __name__ __main__: app.run(debugTrue)步骤3前端页面index.html一个简单的HTML页面使用JavaScript调用上述API实现搜索和展示功能。这里省略具体HTML/CSS代码核心是使用fetch或axios调用/api/poetry/search接口并将返回的JSON数据渲染到页面上。实操心得在真实生产环境中直接遍历内存中的JSON列表进行搜索在数据量巨大时如全唐诗4万多首性能会很差。这只是一个演示。正确的做法是将数据导入专业的数据库如PostgreSQL、Elasticsearch。为author,dynasty,content(或paragraphs) 等字段建立索引。使用数据库的高效查询语言SQL或DSL进行搜索。对于全文搜索Elasticsearch是比关系数据库更优的选择。4.3 数据分析与可视化示例有了结构化数据数据分析就变得非常有趣。我们可以用Python的Pandas和Matplotlib/Seaborn库进行一些简单的探索。import json import pandas as pd from collections import Counter import matplotlib.pyplot as plt # 加载数据 with open(data/poetry/poetry.tang.json, r, encodingutf-8) as f: tang_poems json.load(f) # 1. 转换为Pandas DataFrame df pd.DataFrame(tang_poems) # 2. 统计最活跃的TOP10诗人 top_authors df[author].value_counts().head(10) print(唐代作品数量TOP10诗人) print(top_authors) # 3. 可视化 plt.figure(figsize(10, 6)) top_authors.plot(kindbarh, colorskyblue) plt.xlabel(作品数量) plt.title(唐代诗人作品数量TOP10) plt.gca().invert_yaxis() # 让最多的在上面 plt.tight_layout() plt.show() # 4. 词频分析以李白诗为例 li_bai_df df[df[author] 李白] all_text .join([ .join(p) for p in li_bai_df[paragraphs]]) # 将所有诗句合并成一个字符串 # 使用jieba进行中文分词需要安装pip install jieba import jieba words [word for word in jieba.cut(all_text) if len(word) 1] # 过滤掉单字和标点 word_freq Counter(words).most_common(20) print(\n李白诗中最常出现的20个词语长度1) for word, freq in word_freq: print(f{word}: {freq})通过这样的分析你可以直观地看到唐代的“高产”诗人是谁或者发现李白笔下最常出现的意象是什么如“明月”、“清风”、“长江”等这比单纯的阅读感受要精确得多。5. 常见问题、挑战与优化建议5.1 数据使用中的常见问题编码问题这是最常遇到的坑。确保你的代码文件、终端、数据库和Web服务器的默认编码都是UTF-8。在Python中打开文件时显式指定encodingutf-8是好习惯。数据不一致不同来源的数据合并时可能遇到作者名不一致如“李太白” vs “李白”、朝代标注模糊等问题。项目本身在做归一化但如果你自己添加数据需要建立清洗规则。性能瓶颈如前所述当数据量达到数万甚至数十万条时在内存中进行线性搜索O(n)复杂度是不可接受的。务必使用索引数据库。字段缺失或为空不是每首诗都有notes注释或tags标签。你的代码需要能优雅地处理这些缺失字段使用poem.get(notes, [])而不是poem[notes]来避免KeyError。5.2 高级应用挑战与解决方案挑战一实现高效的全文检索。简单的LIKE或in操作在数据库里效率低下且无法实现模糊匹配和相关性排序。解决方案使用专门的全文检索引擎。Elasticsearch:将诗歌数据导入Elasticsearch利用其强大的中文分词集成IK Analyzer和全文检索能力可以实现毫秒级的复杂关键词、短语搜索并支持高亮显示。PostgreSQL pg_trgm:如果不想引入额外组件PostgreSQL的pg_trgm扩展提供了高效的模糊匹配三元组搜索对于中文也有一定效果。SQLite FTS5:SQLite的FTS5扩展模块也支持全文搜索适合轻量级桌面应用。挑战二基于内容的推荐“找相似的诗”。这是一个更高级的需求涉及到自然语言处理。解决方案使用词向量或句子向量。传统方法TF-IDF 余弦相似度将每首诗表示成一个基于所有诗词词汇的TF-IDF向量然后计算向量间的余弦相似度。相似度高的诗即为内容相似的诗。深度学习方法Sentence-BERT使用预训练的中文模型如paraphrase-multilingual-MiniLM-L12-v2将每首诗的文本编码成一个固定长度的向量嵌入。这些向量捕捉了语义信息计算向量间的相似度可以找到语义上相近的诗即使它们没有共享很多相同的词语。挑战三格律分析与校验。对于诗词研究和创作工具自动分析平仄、押韵是核心功能。解决方案这需要专业的规则库和字典。平仄库需要建立一个中古汉语或根据需求选择普通话的平仄对照字典。每个汉字对应其平仄平、上、去、入。押韵库需要《平水韵》或《词林正韵》等韵书的数据化版本。将诗句的尾字映射到韵部。实现有了这些基础数据就可以编写程序来校验一首诗是否符合特定的格律规则如七律的“仄起首句不入韵”。chinese-poetry项目中的strains字段已经提供了部分诗的平仄信息可以作为基础或校验参考。5.3 项目维护与贡献建议chinese-poetry是一个开源项目它的生命力来自社区。如果你在使用中发现错误或者有新的数据源可以考虑贡献。提交Issue发现错别字、作者信息错误、数据缺失等问题可以在GitHub仓库提交Issue详细描述问题并附上可靠出处。提交Pull Request (PR)如果你有能力修复问题或添加数据可以Fork仓库修改后提交PR。在提交数据时务必遵循项目已有的JSON Schema格式并确保数据来源的可靠性和可追溯性。数据扩展方向除了补充更多的诗、词、曲还可以考虑扩展注释的深度加入历代评点、增加诗歌的创作背景故事、或者建立诗歌与地理位置的关联哪些诗写于黄鹤楼等这些都能极大提升数据的应用价值。我个人在基于这个数据库开发应用时最大的体会是高质量的结构化数据是数字人文项目的基石。chinese-poetry项目提供的正是这样一块坚实的基石。它省去了你从零开始爬取、清洗、校对的漫长而痛苦的过程让你可以专注于创意和功能的实现。无论是做一个给孩子的诗词学习App还是一个供学者研究的文本分析平台它都是一个绝佳的起点。最后一个小技巧在使用前花点时间通读项目的README和文档了解其数据结构和更新日志这能帮你避开很多初期使用时的困惑。本文还有配套的精品资源点击获取