【从文本拆分到关键词挖掘:Python 解锁《红楼梦》文本分析新方式】
本项目以 “文本结构化→特征量化→结果分析” 为核心逻辑,先将非结构化的全文 txt 拆分为结构化章节文件,再通过分词和 TF-IDF 算法实现词汇重要性量化,可快速适配其他长篇文本的分析需求
关键技术点包括:正则匹配定位章节、jieba 分词适配古典文学、TF-IDF 算法量化词汇重要性。
一、技术栈准备
本次实战所需的核心库:
- 基础库:
os(文件 / 路径处理)、re(正则匹配)、pandas(数据结构化); - 中文处理:
jieba(中文分词),支持自定义词库; - 算法库:
sklearn.feature_extraction.text.TfidfVectorizer(TF-IDF 特征提取)。
二、实战步骤:从文本拆分到关键词提取
(一)步骤 1:拆分《红楼梦》为 120 个章节文件
import os # python标准库,不需要安装。关于操作系统的库 import re import pandas as pd # ===================== 核心优化:适配文本格式+解决报错 ===================== # 1. 确保保存目录存在(避免路径不存在报错) output_dir = r'.\红楼梦\分卷1' os.makedirs(output_dir, exist_ok=True) # 2. 打开源文件(使用with语句自动关闭,更安全) with open(r'.\红楼梦\红楼梦.txt', encoding='utf-8') as file: flag = 0 # 用来标记当前是不是在第一次保存文件 juan_file = None # 初始化文件对象,避免未定义报错 # 定义:清理Windows非法文件名字符(解决OSError报错) def clean_filename(filename): illegal_chars = r'[\\/:*?"<>|,。?!;:""''《》()()【】]' clean_name = re.sub(illegal_chars, '', filename) # 移除非法字符 return clean_name[:50] + '.txt' # 限制文件名长度,避免超长 # 定义:精准匹配“卷+回”标题(适配文本中“上卷 第一回 XXX”格式) chapter_pattern = re.compile(r'^[ \s]*([上下]卷\s+第[一二三四五六七八九十百零]+回.*)$', re.MULTILINE) # chapter_pattern = re.compile(r'^[ \s]*([上下]卷)?\s*第([一二三四五六七八九十百]+|[\d]{1,3})回.*$', re.MULTILINE) for line in file: # 开始遍历整个红楼梦 line_strip = line.strip() # 精准匹配“卷+回”标题(核心:只识别章节标题行) match = chapter_pattern.match(line_strip) if match: # 提取纯净的标题(去除前后空格/全角空格) juan_title = match.group(1).strip() # 清理文件名(关键:避免非法字符) juan_name = clean_filename(juan_title) # 构建完整路径 path = os.path.join(output_dir, juan_name) print(f"正在创建文件:{path}") if flag == 0: # 判断是否是第1次读取到卷+回标题 # 关闭初始可能存在的空文件 if juan_file: juan_file.close() # 创建第1个卷文件 juan_file = open(path, 'w', encoding='utf-8') # 写入标题(保留原格式) juan_file.write(line) flag = 1 else: # 不是第1次读取到卷+回标题 # 关闭上一次的文件对象 juan_file.close() # 创建新的卷文件 juan_file = open(path, 'w', encoding='utf-8') # 写入标题(保留原格式) juan_file.write(line) continue # 写入章节内容(仅当文件对象已创建时,避免空写) if juan_file is not None: juan_file.write(line) # 最终关闭文件(避免资源泄露) if juan_file: juan_file.close() print(f"\n✅ 拆分完成!共生成{flag}个卷文件,保存在:{output_dir}")- 正则匹配:覆盖《红楼梦》所有回目标题格式,确保 120 回都能被精准识别;
- 文件名清理:避免因特殊字符导致文件创建失败;
- 文件管理:通过
current_file变量管理当前写入的文件,确保章节内容正确归属
(二)步骤 2:结构化读取章节数据
import pandas as pd import os # 处理操作系统的文件,python标准库,和操作系统打交道! # 41 filePaths = [] # #[#保存文件的路径] filePaths: ['.\\红楼梦\\分卷\\上卷 第一回 甄士隐梦幻识通灵\\u3000'] fileContents = [] # #[#保存文件路径对应的内容] fileContents: [] # 42 for root, dirs, files in os.walk(r'.\红楼梦\分卷1'): # os.walk是直接对文件夹进行遍历 #os.list for name in files: # name: '下卷 第八十四回 试文字宝玉始提亲 探惊风贾环重结怨.txt' filePath = os.path.join(root, name) # root+'\\'+name获取每个文件的路径 #filePath: filePaths.append(filePath) # 将文件路径添加到列表filePaths中 f = open(filePath, 'r', encoding='utf-8') # f: <_io.TextIOWrapper name='.\\红楼梦\\ fileContent = f.read() # 读取每一个的文件中内容 fileContent: " f.close() fileContents.append(fileContent) # 将每一卷的文件内容添加到列表fileContents中 corpos = pd.DataFrame({ # 将文件路径及文件内容添加为DataFrame框架中 numpy ->c corpos: f 'filePath': filePaths, # 'int64' str() float('3.142') 'fileContent': fileContents}) # 训练大家的数据处理能力 print(corpos)目录遍历:自动获取所有章节文件,无需手动指定路径;
结构化存储:将文件路径和内容关联,便于后续按章节处理。
(三)步骤 3:中文分词 + 停用词过滤
import jieba # 保存的词库就是 辞海, 形容词、语气词 不会作为核心关键词的。提前我就剔除TF-IDF的。 jieba.load_userdict(r'.\红楼梦\红楼梦词库.txt') # 导入分词库,把红楼梦专属的单词添加到jieba词库中。 # 导入停用词库 ,把无关心的词提出。 stopwords = pd.read_csv(r'.\红楼梦\StopwordsCN.txt', # StopwordsCN.txt保存的是 常见的助动词 encoding='utf8', engine='python', index_col=False) # engine读取文件时的解析引擎 file_to_jieba = open(r'.\红楼梦\分词后汇总1.txt', 'w', encoding='utf-8') # 创建一个新文本 file_to for index, row in corpos.iterrows(): # iterrows遍历行数据 index: 119 row: ('filePath', # 空的字符串,处理后的单词依次添加到juan_ci后面 juan_ci: '手机 电子书 大学生 小说 fileContent = row['fileContent'] segs = jieba.cut(fileContent) # 对文本内容进行分词,返回一个可遍历的迭代器 segs: <gen for seg in segs: # 遍历每一个词 seg: '\n' if seg not in stopwords.stopword.values and len(seg.strip()) > 0: # 剔除停用词和字符为 juan_ci = juan_ci + seg + ' ' # juan_ci = juan_ci + '电子' + '电子' file_to_jieba.write(juan_ci + '\n') file_to_jieba.close() 自定义词库:解决 jieba 对 “贾宝玉、林黛玉” 等古典文学词汇的识别问题;
停用词过滤:移除无意义词汇,仅保留核心语义词汇,提升后续分析准确性。
(四)步骤 4:TF-IDF 提取核心关键词
from sklearn.feature_extraction.text import TfidfVectorizer import pandas as pd inFile = open(r".\红楼梦\分词后汇总1.txt", 'r', encoding='utf-8') corpus = inFile.readlines() # 返回一个列表,列表一个元素就是一行内容,一行内容一篇分词后的文章 vectorizer = TfidfVectorizer() # 类,转为TF-IDF的向量器 tfidf = vectorizer.fit_transform(corpus) # 传入数据,返回包含TF-IDF的向量值 wordlist = vectorizer.get_feature_names_out() # 获取特征名称,所有的词 df = pd.DataFrame(tfidf.T.todense(), index=wordlist) # tfidf.T.todense() 恢复为稀疏矩阵 # 下面的任务就是对表格进行排序 pandas for i in range(len(corpus)): # 排序,将重要的关键词排序在最前面 featurelist = df.iloc[:, i].to_list() # 通过索引号获取第i列的内容并转换为列表 resdict = {} # 排序以及看输出结果对不对 for j in range(0, len(wordlist)): resdict[wordlist[j]] = featurelist[j] # [('贾宝玉',0.223), ()] resdict = sorted(resdict.items(), key=lambda x: x[1], reverse=True) # 字典的键值对,元组数据类型 print('第{}回的核心关键词:'.format(i+1), resdict[0:10]) TF-IDF 向量转换:将分词文本转为数学矩阵,量化词汇重要性;
关键词排序:按 TF-IDF 值降序排序,提取前 10 个关键词,快速定位章节核心内容。
运行结果:

