Как извлечь текст из файлов OneNote на Python
Файлы Microsoft OneNote .one являются бинарными документами, которые нельзя читать как обычный текст или разбирать с помощью общих XML‑инструментов. Aspose.Note FOSS for Python предоставляет чисто‑Python парсер, который загружает файлы .one в полную модель объектного документа (DOM), что упрощает программное извлечение текста, метаданных форматирования и гиперссылок.
Преимущества использования Aspose.Note FOSS для Python
- Не требуется Microsoft Office: чтение
.oneфайлов на любой платформе, включая серверы Linux CI/CD - Полный доступ к тексту и форматированию: обычный текст, жирный/курсивный/подчёркнутый фрагменты, свойства шрифтов и URL‑адреса гиперссылок
- Бесплатно и с открытым исходным кодом: лицензия MIT, отсутствие платы за использование и API‑ключей
Пошаговое руководство
Шаг 1: Установите Aspose.Note FOSS для Python
Установите библиотеку из 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 сегментов. Каждый run несет независимый 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’
Cause: Пакет не установлен в активной среде Python.
Исправление:
pip install aspose-note
##Confirm active environment:
pip show aspose-note2. FileNotFoundError при загрузке файла .one
Причина: Путь к файлу неверен или файл не существует.
Исправление: используйте абсолютный путь или проверьте, существует ли файл перед загрузкой:
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. UnicodeEncodeError в Windows при печати
Причина: терминалы Windows могут использовать устаревшую кодировку, которая не может отображать символы Unicode.
Исправление: Перенастройте stdout в начале вашего скрипта:
import sys
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8", errors="replace")4. Пустой текст приводит к результатам
Cause: Файл .one может быть пустым, содержать только изображения или таблицы (без узлов RichText), либо быть файлом блокнота (.onetoc2), а не файлом раздела (.one).
Fix: Проверьте количество страниц и типы узлов:
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
Cause: Файл .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 для каждого потока.
Связанные ресурсы: