Jak wyodrębnić tekst z plików OneNote w Pythonie

Jak wyodrębnić tekst z plików OneNote w Pythonie

Pliki Microsoft OneNote .one są dokumentami binarnymi, których nie można odczytać jako zwykły tekst ani parsować przy użyciu ogólnych narzędzi XML. Aspose.Note FOSS for Python udostępnia czysto‑Pythonowy parser, który ładuje pliki .one do pełnego modelu obiektowego dokumentu (DOM), co ułatwia programowe wyodrębnianie tekstu, metadanych formatowania i hiperłączy.

Korzyści z używania Aspose.Note FOSS dla Pythona

  1. Nie wymaga Microsoft Office: odczytuj pliki .one na dowolnej platformie, w tym serwerach CI/CD z Linuxem
  2. Pełny dostęp do tekstu i formatowania: zwykły tekst, pogrubione/pochylone/podkreślone fragmenty, właściwości czcionki oraz adresy URL hiperłączy
  3. Bezpłatny i otwartoźródłowy: licencja MIT, brak opłat za użytkowanie ani kluczy API

Przewodnik krok po kroku

Krok 1: Zainstaluj Aspose.Note FOSS dla Pythona

Zainstaluj bibliotekę z PyPI. Pakiet podstawowy nie ma obowiązkowych zależności:

pip install aspose-note

Sprawdź instalację:

from aspose.note import Document
print("Installation OK")

Krok 2: Załaduj plik .one

Utwórz instancję Document, przekazując ścieżkę do pliku:

from aspose.note import Document

doc = Document("MyNotes.one")
print(f"Section: {doc.DisplayName}")
print(f"Pages:   {len(list(doc))}")

Aby załadować z binarnego strumienia (np. z przechowywania w chmurze lub odpowiedzi HTTP):

from aspose.note import Document

with open("MyNotes.one", "rb") as f:
    doc = Document(f)

Krok 3: Wyodrębnij cały tekst zwykły

Użyj GetChildNodes(RichText), aby zebrać każdy węzeł RichText w drzewie dokumentu. To wykonuje rekurencyjne przeszukiwanie w głąb we wszystkich stronach, konturach i elementach konturu:

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)

Aby zapisać cały tekst do pliku:

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")

Krok 4: Sprawdź sformatowane fragmenty

Każdy węzeł RichText zawiera listę TextRuns segmentów TextRun. Każdy run niesie niezależny TextStyle z formatowaniem na poziomie znaków:

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}")

Krok 5: Wyodrębnij hiperłącza

Odnośniki są przechowywane w poszczególnych węzłach TextRun. Sprawdź Style.IsHyperlink i przeczytaj 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}")

Krok 6: Wyodrębnij tekst na stronę

Aby wyodrębnić tekst zorganizowany według tytułu strony:

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)

Typowe problemy i rozwiązania

1. ImportError: Brak modułu o nazwie ‘aspose’

Przyczyna: Pakiet nie jest zainstalowany w aktywnym środowisku Pythona.

Poprawka:

pip install aspose-note
##Confirm active environment:
pip show aspose-note

2. FileNotFoundError podczas ładowania pliku .one

Przyczyna: Ścieżka do pliku jest nieprawidłowa lub plik nie istnieje.

Naprawa: Użyj ścieżki bezwzględnej lub sprawdź, czy plik istnieje przed wczytaniem:

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 w systemie Windows podczas drukowania

Przyczyna: Terminale Windows mogą używać starszego kodowania, które nie potrafi wyświetlać znaków Unicode.

Fix: Przekonfiguruj stdout na początku swojego skryptu:

import sys
if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")

4. Wyniki pustego tekstu

Przyczyna: Plik .one może być pusty, zawierać tylko obrazy lub tabele (brak węzłów RichText), lub być plikiem notatnika (.onetoc2) zamiast pliku sekcji (.one).

Naprawa: Sprawdź liczbę stron i zbadaj typy węzłów:

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

Przyczyna: Plik .one jest zaszyfrowany. Zaszyfrowane dokumenty nie są obsługiwane.

Fix: Aspose.Note FOSS for Python nie obsługuje zaszyfrowanych plików .one. Pełnofunkcyjny komercyjny produkt Aspose.Note obsługuje odszyfrowywanie.


Najczęściej zadawane pytania

Czy mogę wyodrębnić tekst ze wszystkich stron jednocześnie?

Tak. doc.GetChildNodes(RichText) przeszukuje całe drzewo dokumentu rekurencyjnie, włączając wszystkie strony, konspekty i elementy konspektu.

Czy biblioteka obsługuje pliki notatnika .onetoc2?

Nie. Biblioteka obsługuje wyłącznie pliki sekcji .one. Pliki spisu treści notatnika (.onetoc2) są innym formatem i nie są obsługiwane.

Czy mogę wyodrębnić tekst z tabel?

Tak. TableCell węzły zawierają RichText dzieci, które można odczytać w ten sam sposób:

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()

Jakie wersje Pythona są obsługiwane?

Python 3.10, 3.11 i 3.12.

Czy biblioteka jest bezpieczna wątkowo?

Każda instancja Document powinna być używana z jednego wątku. W przypadku równoległego wyodrębniania utwórz osobną Document dla każdego wątku.


Powiązane zasoby:

 Polski