如何在 Python 中从 OneNote 文件中提取文本
Microsoft OneNote .one 文件是二进制文档,无法以纯文本读取或使用通用 XML 工具解析。Aspose.Note FOSS for Python 提供了一个纯 Python 解析器,可将 .one 文件加载到完整的文档对象模型(DOM)中,从而可以轻松以编程方式提取文本、格式元数据和超链接。
使用 Aspose.Note FOSS for Python 的好处
- 无需 Microsoft Office:在任何平台上读取
.one文件,包括 Linux CI/CD 服务器 - 完整的文本和格式访问:纯文本、粗体/斜体/下划线运行、字体属性以及超链接 URL
- 免费且开源:MIT 许可证,无使用费用或 API 密钥
逐步指南
步骤 1:为 Python 安装 Aspose.Note FOSS
从 PyPI 安装库。核心包没有强制依赖:
pip install aspose-note验证安装:
from aspose.note import Document
print("Installation OK")步骤 2:加载 .one 文件
通过传递文件路径创建一个 Document 实例:
from aspose.note import Document
doc = Document("MyNotes.one")
print(f"Section: {doc.DisplayName}")
print(f"Pages: {len(list(doc))}")从二进制流加载(例如来自云存储或 HTTP 响应):
from aspose.note import Document
with open("MyNotes.one", "rb") as f:
doc = Document(f)步骤 3:提取所有纯文本
使用 GetChildNodes(RichText) 收集文档树中每个 RichText 节点。此操作在所有页面、提纲和提纲元素中执行递归深度优先搜索:
from aspose.note import Document, RichText
doc = Document("MyNotes.one")
texts = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text]
for text in texts:
print(text)将所有文本保存到文件:
from aspose.note import Document, RichText
doc = Document("MyNotes.one")
texts = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text]
with open("extracted_text.txt", "w", encoding="utf-8") as out:
out.write("\n".join(texts))
print(f"Wrote {len(texts)} text blocks to extracted_text.txt")步骤 4:检查格式化的运行
每个 RichText 节点包含一个 TextRuns 列表,其中包含 TextRun 段落。每个运行携带一个独立的 TextStyle,并具有逐字符的格式设置:
from aspose.note import Document, RichText
doc = Document("MyNotes.one")
for rt in doc.GetChildNodes(RichText):
for run in rt.TextRuns:
style = run.Style
attrs = []
if style.IsBold: attrs.append("bold")
if style.IsItalic: attrs.append("italic")
if style.IsUnderline: attrs.append("underline")
if style.IsStrikethrough: attrs.append("strikethrough")
if style.FontName: attrs.append(f"font={style.FontName}")
if style.FontSize: attrs.append(f"size={style.FontSize}pt")
label = ", ".join(attrs) if attrs else "plain"
print(f"[{label}] {run.Text!r}")步骤 5:提取超链接
超链接存储在各个 TextRun 节点上。检查 Style.IsHyperlink 并阅读 Style.HyperlinkAddress:
from aspose.note import Document, RichText
doc = Document("MyNotes.one")
for rt in doc.GetChildNodes(RichText):
for run in rt.TextRuns:
if run.Style.IsHyperlink and run.Style.HyperlinkAddress:
print(f"Link text: {run.Text!r}")
print(f"URL: {run.Style.HyperlinkAddress}")第6步:逐页提取文本
提取按页面标题组织的文本:
from aspose.note import Document, Page, RichText
doc = Document("MyNotes.one")
for page in doc.GetChildNodes(Page):
title = (
page.Title.TitleText.Text
if page.Title and page.Title.TitleText
else "(untitled)"
)
print(f"\n=== {title} ===")
for rt in page.GetChildNodes(RichText):
if rt.Text:
print(rt.Text)常见问题及解决方案
1. ImportError: 未找到名为 ‘aspose’ 的模块
原因: 该包未安装在当前的 Python 环境中。
修复:
pip install aspose-note
##Confirm active environment:
pip show aspose-note2. 加载 .one 文件时出现 FileNotFoundError
原因: 文件路径不正确或文件不存在。
Fix: 使用绝对路径或在加载前验证文件是否存在:
from pathlib import Path
from aspose.note import Document
path = Path("MyNotes.one")
if not path.exists():
raise FileNotFoundError(f"File not found: {path.resolve()}")
doc = Document(str(path))3. 在 Windows 上打印时出现 UnicodeEncodeError
原因: Windows 终端可能使用无法呈现 Unicode 字符的旧版编码。
Fix: 在脚本开始时重新配置 stdout:
import sys
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8", errors="replace")4. 空文本结果
Cause: .one 文件可能为空,仅包含图像或表格(没有 RichText 节点),或者是笔记本文件(.onetoc2),而不是节文件(.one)。
修复: 检查页面计数并检查节点类型:
from aspose.note import Document
doc = Document("MyNotes.one")
print(f"Pages: {len(list(doc))}")
for page in doc:
print(f" Children: {sum(1 for _ in page)}")5. IncorrectPasswordException
原因: .one 文件已加密。不支持加密文档。
Fix: Aspose.Note FOSS for Python 不支持加密的 .one 文件。功能完整的商业版 Aspose.Note 产品支持解密。
常见问题
我可以一次提取所有页面的文本吗?
是的。doc.GetChildNodes(RichText) 递归搜索整个文档树,包括所有页面、提要和提要元素。
该库是否支持 .onetoc2 笔记本文件?
不。该库仅处理 .one 部分文件。笔记本目录文件(.onetoc2)是另一种格式,不受支持。
我可以从表格中提取文本吗?
是的。 TableCell 节点包含 RichText 子节点,可以以相同的方式读取:
from aspose.note import Document, Table, TableRow, TableCell, RichText
doc = Document("MyNotes.one")
for table in doc.GetChildNodes(Table):
for row in table.GetChildNodes(TableRow):
for cell in row.GetChildNodes(TableCell):
cell_text = " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip()
print(cell_text, end="\t")
print()支持哪些 Python 版本?
Python 3.10、3.11 和 3.12。
该库是线程安全的吗?
每个 Document 实例应仅在单个线程中使用。对于并行提取,请为每个线程创建一个单独的 Document。
相关资源: