如何在 Python 中从 OneNote 文件中提取文本

如何在 Python 中从 OneNote 文件中提取文本

Microsoft OneNote .one 文件是二进制文档,无法以纯文本读取或使用通用 XML 工具解析。Aspose.Note FOSS for Python 提供了一个纯 Python 解析器,可将 .one 文件加载到完整的文档对象模型(DOM)中,从而可以轻松以编程方式提取文本、格式元数据和超链接。

使用 Aspose.Note FOSS for Python 的好处

  1. 无需 Microsoft Office:在任何平台上读取 .one 文件,包括 Linux CI/CD 服务器
  2. 完整的文本和格式访问:纯文本、粗体/斜体/下划线运行、字体属性以及超链接 URL
  3. 免费且开源: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-note

2. 加载 .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


相关资源:

 中文