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
- Nie wymaga Microsoft Office: odczytuj pliki
.onena dowolnej platformie, w tym serwerach CI/CD z Linuxem - 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
- 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-noteSprawdź 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-note2. 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: