💡 مثال كامل يعمل متوفر على GitHub:
sanitize-office-document-pii-python

البيانات التي لا يراجعها أحد قبل الضغط على إرسال

يتم إرسال تقرير ربع سنوي إلى مدقق خارجي. النص خالٍ من الأخطاء؛ ثلاث دورات مراجعة تأكدت من ذلك. الملف نفسه قصة أخرى. لا تزال خصائصه تحمل اسم المحلل الذي صاغه، والمدير الذي أعاد صياغته، والشركة الفرعية التي تملك القالب، وطابع زمن LastPrinted من الليلة التي سبقت الموعد النهائي، ومعرف موافق SharePoint من سير عمل الموافقة الداخلي. لا يظهر أي من هذا على أي صفحة. كل ذلك يسافر مع الملف.

إزالة المعلومات الشخصية (PII) هي سير عمل GroupDocs.Metadata للغة Python عبر .NET يزيل هذه الخصائص التي تحمل هوية من ملفات Word وExcel وPowerPoint برمجيًا. تقارن هذه المقالة بين الثلاثة أساليب التي يقدمها API: الإزالة المدفوعة بالوسوم للحقول الهوية، الإزالة المدفوعة بنمط الاسم لعائلات الخصائص مثل التعليقات والتنقيحات، والنداء الواحد sanitize() الذي يمسح كل شيء. سترى أيضًا الخطوة التي يتخطاها معظم سكريبتات التنظيف، وهي فحص التحقق الذي يثبت أن التنظيف تم فعلاً.

لماذا تستحق معلومات التعريف (Metadata) المتعلقة بالـ PII خط أنابيب خاص بها

أدوات مراجعة المحتوى تتحقق مما يقرأه الأشخاص. لا تتحقق مما تخزنه أنظمة الملفات، وهذه الفجوة هي مصدر حوادث الامتثال. طلب GDPR يغطي البيانات الشخصية في حقول Author وManager بقدر ما يغطي البيانات في النص. الاكتشاف القانوني يقرأ عدادات التنقيحات وإجماليات وقت التحرير لإعادة بناء مدة التفاوض على ورقة موقف. يمكن لمراجعي العطاءات رسم هيكل مؤسستك من خصائص سير عمل SharePoint، وتحتفظ حقول التعليقات في بيان صحفي بأسماء المراجعين إلى جانب ملاحظات مرحلة المسودة. كل ذلك اكتشاف. لا شيء منها مرئي في جسم المستند.

المتطلبات المسبقة

قبل البدء، تأكد من أن لديك:

  • Python 3 مع pip
  • GroupDocs.Metadata للغة Python عبر .NET، مثبت في مستودع العينة على الإصدار 26.5
  • ملف Office يحتوي على خصائص حقيقية للتدرب عليها

التثبيت

pip install groupdocs-metadata-net==26.5

المستودع المرافق يزرع ملف DOCX نموذجي ويشغل كل مقتطف أدناه كسطر أنابيب مؤكد.

الطريقة 1: إزالة الهوية المدفوعة بالوسوم

أكثر الحقول حساسيةً هي Author وLastSavedBy وManager وCompany، ولكل منها أسماء داخلية مختلفة عبر صيغ Office. يحل نظام الوسوم هذه المشكلة: بدلاً من تسمية الخصائص، يطلب المتنبئ كل ما تم وسمه كشخص أو شركة.

# Match identity properties by meaning, not by format-specific name
with Metadata("board-report.docx") as metadata:
    removed = metadata.remove_properties(lambda p:
        Tags.person.creator in list(p.tags)     # Author, LastSavedBy
        or Tags.person.editor in list(p.tags)
        or Tags.person.manager in list(p.tags)
        or Tags.corporate.company in list(p.tags))
    metadata.save("board-report-clean.docx")

print(f"{removed} identity properties removed")

نقاط رئيسية:

  • استقلالية الصيغة: نفس الدالة lambda تنظف DOCX وXLSX وPPTX لأن الوسوم تصنف حسب الدور.
  • نتيجة قابلة للعد: remove_properties تُعيد عدد الخصائص التي تم مطابقتها، وهذا ما يندرج في سجل التدقيق الخاص بك.
  • نسخ semantically: الحفظ إلى مسار جديد يحتفظ بالأصل لسجلاتك.

💡 نصيحة: هذه العملية تحافظ على Title وSubject وغيرها من الحقول الوصفية، لذا يبقى الملف صديقًا للبحث وفهرسة أنظمة إدارة المستندات (DMS).

الطريقة 2: إزالة مدفوعة بنمط الاسم لعائلات الخصائص

الوسوم تغطي المفاهيم المصنفة. عائلات كاملة من الحقول المتسربة تقع خارج هذا التصنيف: خصائص التعليقات، عدادات التنقيحات، طوابع سير عمل SharePoint. لهذه الحالات، يتم المطابقة على اسم الخاصية نفسه.

# Comment fields often live in custom properties the tag system
# does not classify, so match them by name substring
with Metadata("board-report.docx") as metadata:
    removed = metadata.remove_properties(lambda p:
        p.name is not None and (
            "Comment" in p.name
            or "Reviewer" in p.name
            or "Reviewed" in p.name))
    metadata.save("board-report-no-comments.docx")

نفس الشكل يتعامل مع العائلتين الأخريين؛ فقط قائمة السلاسل الفرعية تتغير:

العائلة السلاسل الفرعية للمطابقة
مسار التنقيحات Revision, TrackedChange, LastPrinted, TotalEditingTime, EditTime
الخادم / سير العمل Server, Workflow, Approver, ContentType, Template

هذا يبادل الدقة بالوصول: "Comment" يلتقط أيضًا Comments وCommentCount، وهو ما يرغبه عادةً تمرير التنظيف. السلاسل العامة قد تطابق حقول القالب غير الضارة أيضًا، لذا راقب العدد المرجع مقابل توقعاتك.

💡 نصيحة: شغّل كل عائلة كتمرير منفصل عندما يحتاج سجل التدقيق إلى عدد لكل فئة؛ دمج السلاسل في متنبئ واحد عندما لا تكون الحاجة لذلك.

الطريقة 3: نداء واحد للتنظيف الكامل

عندما يغادر الملف المؤسسة ولا يجب أن يبقى أي شيء في طبقة التعريفات، توقف عن كتابة المتنبئات.

# One call, every detected metadata package
with Metadata("board-report.docx") as metadata:
    removed = metadata.sanitize()
    metadata.save("board-report-final.docx")

print(f"sanitize() removed {removed} properties")

sanitize() يمسح كل حزمة يكتشفها المكتبة: حقول هوية معلومات الوثيقة، التعليقات، تاريخ التنقيحات، مؤلفي التغييرات المتعقبة، وأجزاء OOXML مخصصة. السلوك موثق في صفحة Clean metadata. قوته هي أيضًا تكلفةه. يختفي Title وSubject مع الـ PII، لذا يفضل استخدامها عند بوابة التصدير وليس في وسط سير عمل التعاون.

هل أحتاج إلى جميع الأربعة تمريرات المستهدفة؟

لا. كل تمريرة موجودة لأن فريقًا مختلفًا يتحمل المخاطر. حقول الهوية تزعج مسؤولي الخصوصية، مسارات التعليقات تزعج القانونية، عدادات التنقيحات تزعج المفاوضين، وحقول الخادم تزعج الأمن. شغّل التمريرات التي تتطابق مع مراجعيك، بأي ترتيب، لأن كل واحدة تكتب نسختها الخاصة. عندما لا يحتاج أحد إلى حقول باقية، انتقل مباشرة إلى sanitize() وتحقق.

مقارنة بين الثلاثة أساليب

الأسلوب الأنسب لـ المزايا الرئيسية القيود
الإزالة المدفوعة بالوسوم نسخ العمل، أنابيب متعددة الصيغ مستقل عن الصيغة، يحافظ على الحقول الوصفية يغطي فقط المفاهيم المصنفة بالوسوم
الإزالة المدفوعة بنمط الاسم التعليقات، التنقيحات، حقول الخادم يصل إلى الخصائص المخصصة التي لا تغطيها الوسوم تحتاج السلاسل الفرعية إلى ضبط حسب البيئة
التنظيف الكامل sanitize() التصدير النهائي خارج المؤسسة لا يمكن أن يفوت خاصية منسية يمحو الحقول غير الضارة أيضًا

تتداخل الأساليب بطبيعتها: تمريرات مستهدفة أثناء بقاء المستند، sanitize() عند شحنه.

التحقق قبل الوثوق

إرجاع عدد من عملية الإزالة ليس دليلًا على أن الملف نظيف. ينهي المستودع كل تشغيل بإعادة فتح المخرجات المنقاة وفحصها باستخدام find_properties، مع متنبئ يجمع قواعد الوسوم وقواعد الاسم من جميع التمريرات أعلاه.

def is_pii(p):
    if p.name is None:
        return False
    return (
        Tags.person.creator in list(p.tags)
        or Tags.person.editor in list(p.tags)
        or Tags.person.manager in list(p.tags)
        or Tags.corporate.company in list(p.tags)
        or any(n in p.name for n in (
            "Comment", "Reviewer", "Revision", "TrackedChange",
            "Classification", "Department", "Server", "Workflow")))

with Metadata("board-report-final.docx") as metadata:
    for p in metadata.find_properties(is_pii):
        value = (str(p.interpreted_value) if p.interpreted_value is not None
                 else (str(p.value) if p.value is not None else ""))
        if value and value not in ("0", "0.0"):
            print(f"LEAK {p.name}={value}")

الإصدار الكامل في المستودع يصنف الباقين إلى دلوين، والتمييز مهم. يجب أن تكون تسريبات التعريفات صفرًا. البقايا على مستوى المحتوى—فقاعات تعليقات Word والتغييرات المتعقبة داخل word/document.xml—هي محتوى جسدي لا يمكن لواجهة برمجة تطبيقات التعريفات الوصول إليه؛ إزالتها تتطلب مكتبة تحرير محتوى مثل Aspose.Words. تقرير صادق يذكر كلا الدلوين بدلاً من إعلان النصر بعد الفحص الأول. في المرة الأولى التي شغلت فيها هذا الفحص على ملف “نظيف”، تم الإشارة إلى حقل Department كان قالب الشركة يضيفه بهدوء لعدة أشهر.

أفضل الممارسات والنصائح

  • نظّف النسخ، لا الأصلي: كل مقتطف هنا يكتب إلى مسار جديد، محافظًا على المصدر لسجلاتك وقواعد الاحتفاظ.
  • سجّل الأعداد: القيم المرجعة من remove_properties وsanitize() هي سجل التدقيق الخاص بك. احفظها لكل ملف، لكل تمريرة.
  • دمج التحقق في CI: فحص التسرب الذي يفشل البناء يلتقط تراجع القوالب في اليوم الذي يحدث فيه، لا في اليوم الذي يلاحظه العميل.
  • الانتباه إلى حد الفاصل بين التعريفات والمحتوى: لا تُعلن أن الملف نظيف بينما تبقى تعليقات على مستوى النص؛ اعرضها كاكتشاف منفصل.
  • الترخيص: وضع التقييم يعيد كل شيء في هذه المقالة؛ استخدم ترخيصًا في الإنتاج حتى لا تلمس علامات التقييم الملفات الصادرة.

الخلاصة

ثلاثة أساليب، قاعدة قرار واحدة. طابق بالوسم عندما يكون المفهوم مصنفًا ويجب أن يبقى الملف مفيدًا. طابق بالاسم عندما تعيش العائلة في خصائص مخصصة. استدعِ sanitize() عندما يعبر الملف حد الثقة، وتحقق بفحص قراءة عكسي مهما كان المسار الذي اخترته.

هل تريد الغوص أعمق؟ إليك بعض الخطوات التالية:

موارد إضافية

هل لديك أسئلة أو تريد مشاركة تنفيذك؟ تواصل عبر support forum.