💡 Pełny działający przykład dostępny na GitHubie:
sanitize-office-document-pii-python
Dane, których nikt nie przegląda przed naciśnięciem „Wyślij”
Kwartalny raport zarządu jest wysyłany do zewnętrznego audytora. Tekst jest bez skazy; trzy cykle recenzji to potwierdziły. Sam plik to inna historia. Jego właściwości wciąż zawierają imię i nazwisko analityka, który go opracował, menedżera, który go przerobił, spółkę zależną, której należy szablon, znacznik czasu LastPrinted z nocy przed terminem oraz identyfikator zatwierdzającego w SharePoint z wewnętrznego procesu akceptacji. Nic z tego nie pojawia się na żadnej stronie. Wszystko podróżuje razem z plikiem.
Usuwanie PII to przepływ pracy GroupDocs.Metadata dla Pythona poprzez .NET, który programowo usuwa te właściwości niosące tożsamość z plików Word, Excel i PowerPoint. Ten artykuł porównuje trzy podejścia oferowane przez API: usuwanie oparte na tagach dla pól tożsamości, usuwanie oparte na wzorcach nazw dla rodzin właściwości takich jak komentarze i wersje, oraz jednorazowe wywołanie sanitize(), które czyści wszystko. Zobaczysz także krok, który pomijają większość skryptów sanitizujących – skan weryfikacyjny, który dowodzi, że czyszczenie rzeczywiście się powiodło.
Dlaczego metadane PII zasługują na własny potok
Narzędzia do przeglądu treści sprawdzają, co ludzie czytają. Nie sprawdzają, co przechowują systemy plików, a właśnie w tej luce powstają incydenty zgodności. Żądanie GDPR obejmuje dane osobowe w polach Author i Manager tak samo, jak dane w tekście. Odkrycie prawne odczytuje liczniki wersji i sumy czasu edycji, aby odtworzyć, jak długo negocjowano dokument stanowiskowy. Recenzenci przetargów mogą odtworzyć strukturę organizacyjną z właściwości przepływu pracy SharePoint, a pola komentarzy w komunikacie prasowym zachowują nazwiska recenzentów obok uwag w fazie szkicu. Każde z nich to znalezisko. Żadne nie jest widoczne w treści dokumentu.
Wymagania wstępne
Przed rozpoczęciem upewnij się, że masz:
- Python 3 z pip
- GroupDocs.Metadata dla Pythona poprzez .NET, zablokowany w repozytorium przykładowym do wersji 26.5
- Plik Office z rzeczywistymi właściwościami do ćwiczeń
Instalacja
pip install groupdocs-metadata-net==26.5
Repozytorium towarzyszące dostarcza przykładowy DOCX i uruchamia każdy fragment kodu jako zweryfikowany potok.
Metoda 1: Usuwanie tożsamości oparte na tagach
Cztery najczułe pola – Author, LastSavedBy, Manager i Company – mają różne wewnętrzne nazwy w formatach Office. System tagów rozwiązuje ten problem: zamiast nazywać właściwości, predykat pyta o wszystko oznaczone jako osoba lub firma.
# 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")
Kluczowe punkty:
- Niezależność od formatu: ta sama funkcja lambda czyści DOCX, XLSX i PPTX, ponieważ tagi klasyfikują według roli.
- Wynik liczbowy:
remove_propertieszwraca liczbę dopasowanych właściwości, co powinno trafić do Twojego dziennika audytu. - Semantyka kopiowania: zapis do nowej ścieżki zachowuje oryginał dla Twoich rekordów.
💡 Wskazówka: ten przebieg zachowuje pola Title, Subject i inne opisowe, więc plik pozostaje przyjazny dla wyszukiwania i indeksowania DMS.
Metoda 2: Usuwanie oparte na wzorcach nazw dla rodzin właściwości
Tagi obejmują sklasyfikowane pojęcia. Całe rodziny przeciekających pól znajdują się poza tą klasyfikacją: właściwości komentarzy, liczniki wersji, znaczniki przepływu pracy SharePoint. Dla nich dopasowujemy się do samej nazwy właściwości.
# 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")
Ten sam szkielet obsługuje pozostałe dwie rodziny; zmienia się jedynie lista podciągów:
| Rodzina | Podciągi do dopasowania |
|---|---|
| Ścieżka wersji | Revision, TrackedChange, LastPrinted, TotalEditingTime, EditTime |
| Serwer / przepływ pracy | Server, Workflow, Approver, ContentType, Template |
To wymiana precyzji na zasięg: "Comment" łapie także Comments i CommentCount, co zazwyczaj jest pożądane w przebiegu sanitizacji. Szerokie podciągi mogą również dopasować nieszkodliwe pola szablonu, więc porównaj zwróconą liczbę z oczekiwaniami.
💡 Wskazówka: uruchamiaj każdą rodzinę jako oddzielny przebieg, gdy Twój dziennik audytu wymaga liczby na kategorię; scal podciągi w jeden predykat, gdy nie jest to konieczne.
Metoda 3: Jednokrotne wywołanie pełnego sanitizowania
Gdy plik opuszcza organizację i nic w warstwie metadanych nie powinno przetrwać, przestań pisać predykaty.
# 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() usuwa każdy pakiet metadanych wykryty przez bibliotekę: pola tożsamości w informacji o dokumencie, komentarze, historię wersji, autorów zmian śledzonych oraz niestandardowe części OOXML. Zachowanie jest opisane na stronie Clean metadata. Jego siłą jest także koszt. Title i Subject znikają wraz z PII, dlatego powinno się go używać na bramce eksportu, a nie w środku współpracy.
Czy potrzebuję wszystkich czterech ukierunkowanych przebiegów?
Nie. Każdy przebieg istnieje, ponieważ inny zespół odpowiada za ryzyko. Pola tożsamości niepokoją oficerów prywatności, ścieżki komentarzy niepokoją prawników, liczniki wersji niepokoją negocjatorów, a pola serwerowe niepokoją bezpieczeństwo. Uruchamiaj te, które odpowiadają Twoim recenzentom, w dowolnej kolejności, ponieważ każdy zapisuje własną kopię wyjściową. Gdy nikt nie potrzebuje zachowanych pól, przejdź od razu do sanitize() i zweryfikuj.
Porównanie trzech podejść
| Metoda | Najlepsze dla | Kluczowe zalety | Ograniczenia |
|---|---|---|---|
| Tag-driven removal | Kopie robocze, wieloformatowe potoki | Niezależność od formatu, zachowuje pola opisowe | Obejmuje tylko pojęcia sklasyfikowane tagami |
| Name-pattern removal | Komentarze, wersje, pola serwerowe | Dociera do własności niestandardowych, które tagi pomijają | Podciągi wymagają dostrojenia do środowiska |
| Full sanitize() | Końcowy eksport poza organizację | Nie może pominąć zapomnianej właściwości | Usuwa także nieszkodliwe pola |
Podejścia komponują się naturalnie: ukierunkowane przebiegi, gdy dokument jest aktywny, sanitize() przy wysyłce.
Zweryfikuj, zanim uwierzysz
Zwrócenie liczby usuniętych elementów nie jest dowodem, że plik jest czysty. Repozytorium kończy każdy przebieg ponownym otwarciem wyczyszczonego wyjścia i skanowaniem go za pomocą find_properties, używając predykatu łączącego reguły tagów i nazwy ze wszystkich powyższych przebiegów.
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}")
Pełna wersja w repozytorium sortuje pozostałości w dwa koszyki, a rozróżnienie ma znaczenie. Wycieki metadanych muszą wynosić zero. Pozostałości na poziomie treści – balony komentarzy Worda i zmiany śledzone wewnątrz word/document.xml – to zawartość ciała, której API metadanych nie może dosięgnąć; ich usunięcie wymaga biblioteki edytującej treść, takiej jak Aspose.Words. Rzetelny raport wymienia oba koszyki zamiast ogłaszać zwycięstwo po pierwszym. Przy pierwszym uruchomieniu tego skanu na „czystym” pliku, wykryto pole Department, które szablon korporacyjny cicho dodawał od miesięcy.
Najlepsze praktyki i wskazówki
- Sanityzuj kopie, nigdy oryginały: każdy fragment kodu zapisuje do nowej ścieżki, zachowując źródło dla Twoich rekordów i zasad retencji.
- Loguj liczby: wartości zwracane przez
remove_propertiesisanitize()to Twój ślad audytu. Przechowuj je per plik, per przebieg. - Wbuduj weryfikację w CI: kontrola wycieków, która przerywa budowę, łapie regresje szablonów w dniu ich wystąpienia, a nie w dniu, gdy klient to zauważy.
- Zwróć uwagę na granicę metadane/treść: nigdy nie deklaruj pliku jako czystego, gdy wciąż istnieją komentarze w treści; zgłoś je jako oddzielne znalezisko.
- Licencjonowanie: tryb ewaluacyjny odtwarza wszystko w tym artykule; użyj licencji w produkcji, aby żadne oznaczenia ewaluacyjne nie trafiły do wychodzących plików.
Zakończenie
Trzy podejścia, jedna reguła decyzyjna. Dopasuj tag, gdy pojęcie jest sklasyfikowane i plik musi pozostać użyteczny. Dopasuj nazwę, gdy rodzina mieszka w własnościach niestandardowych. Wywołaj sanitize(), gdy plik przekracza granicę zaufania, i zweryfikuj skanem odczytu, którąkolwiek drogą poszedłeś.
Gotowy na głębsze zanurzenie? Oto kolejne kroki:
- Przestudiuj powierzchnię predykatu na stronie dokumentacji Remove metadata properties
- Śledź step-by-step use case guide oparty na tym samym kodzie
- Sklonuj sample repository i uruchom zweryfikowany potok na własnych plikach
Dodatkowe zasoby
- GroupDocs.Metadata Documentation
- API Reference
- Sample Projects on GitHub
- GroupDocs.Metadata Blog Category
Masz pytania lub chcesz podzielić się swoją implementacją? Skontaktuj się na support forum.