چگونه متن را از فایل‌های OneNote در پایتون استخراج کنیم

چگونه متن را از فایل‌های OneNote در پایتون استخراج کنیم

فایل‌های Microsoft OneNote .one اسناد باینری هستند که نمی‌توان آنها را به‌صورت متن ساده خواند یا با ابزارهای عمومی XML تجزیه کرد. Aspose.Note FOSS for Python یک تجزیه‌گر کاملاً پایتونی ارائه می‌دهد که فایل‌های .one را به یک مدل شیء سند کامل (DOM) بارگذاری می‌کند و استخراج متن، فراداده‌های قالب‌بندی و پیوندهای فراخوانی را به‌صورت برنامه‌نویسی ساده می‌سازد.

مزایای استفاده از Aspose.Note FOSS برای پایتون

  1. بدون نیاز به Microsoft Office: فایل‌های .one را در هر پلتفرمی، از جمله سرورهای CI/CD لینوکس، بخوانید
  2. دسترسی کامل به متن و قالب‌بندی: متن ساده، بخش‌های بولد/ایتالیک/زیرخط، خصوصیات قلم، و URLهای پیوند
  3. رایگان و منبع باز: مجوز MIT، بدون هزینه استفاده یا کلیدهای API

راهنمای گام به گام

مرحله ۱: نصب Aspose.Note FOSS برای Python

کتابخانه را از PyPI نصب کنید. بستهٔ هسته‌ای هیچ وابستگی اجباری ندارد:

pip install aspose-note

نصب را تأیید کنید:

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

مرحله ۲: بارگذاری فایل .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)

مرحله ۳: استخراج تمام متن ساده

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

مرحله ۴: بررسی اجراهای قالب‌بندی‌شده

هر گره 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’ یافت نشد

Cause: بسته در محیط فعال پایتون نصب نشده است.

رفع:

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

2. FileNotFoundError هنگام بارگذاری فایل .one

Cause: مسیر فایل نادرست است یا فایل وجود ندارد.

رفع: از مسیر مطلق استفاده کنید یا قبل از بارگذاری وجود فایل را تأیید کنید:

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 در ویندوز هنگام چاپ

دلیل: ترمینال‌های ویندوز ممکن است از یک رمزگذاری قدیمی استفاده کنند که قادر به رندر کردن کاراکترهای یونیکد نیست.

رفع: پیکربندی مجدد stdout در ابتدای اسکریپت خود:

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

4. نتایج متن خالی

دلیل: فایل .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

دلیل: فایل .one رمزگذاری شده است. اسناد رمزگذاری شده پشتیبانی نمی‌شوند.

رفع: Aspose.Note FOSS برای 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()

کدام نسخه‌های پایتون پشتیبانی می‌شوند؟

پایتون 3.10، 3.11 و 3.12.

آیا کتابخانه thread-safe است؟

هر نمونه Document باید از یک رشته استفاده شود. برای استخراج موازی، یک Document جداگانه برای هر رشته ایجاد کنید.


منابع مرتبط:

 فارسی