Khi bàn giao các tài liệu có chú thích, đừng chỉ giao một bản PDF trông sạch sẽ.

Bài viết này cung cấp giải pháp xác minh bảo mật và trích xuất theo lớp dựa trên PyMuPDF để giải quyết các vấn đề nhầm lẫn giữa văn bản và nhận xét, rò rỉ dữ liệu nhạy cảm và nhầm lẫn hệ tọa độ trong trích xuất chú thích PDF. Nội dung bao gồm nguyên tắc lớp dữ liệu độc lập, ví dụ về lập trình phòng thủ, xử lý điều kiện biên và tiêu chí chấp nhận thủ công, đồng thời giải thích cách kết nối OmniDoc chính xác trong quy trình dịch tài liệu để so sánh và chấp nhận song ngữ.

Trước khi bàn giao các chú thích PDF, nhiều người sẽ trực tiếp sử dụng page.get_text() để xuất văn bản trông đẹp mắt để dịch, lưu trữ hoặc bàn giao cho người đánh giá tiếp theo. Nhưng văn bản này thường không chứa chú thích. Một số phương pháp trích xuất còn chèn chú thích vào giữa văn bản, làm gián đoạn ngữ nghĩa; những nhận xét sửa đổi và nhận xét nhạy cảm ở thanh bên có thể bị bỏ sót.

Bài viết này được viết dành cho các nhà phát triển và chủ sở hữu tài liệu, những người cần làm việc với các tệp PDF có chú thích. Sau khi đọc, bạn sẽ hiểu tại sao chú thích là các lớp dữ liệu độc lập, cách trích xuất văn bản và chú thích trong các lớp, trường hợp cạnh nào cần được xử lý phòng thủ và điểm chấp nhận nào phải được xác nhận thủ công.

Các ví dụ trong bài viết này đều sử dụng mẫu tổng hợp. Mã đã được kiểm tra mẫu trong một môi trường biệt lập, nhưng điều này không đảm bảo cho tất cả các tệp thực hoặc hiệu suất của sản phẩm. Trước khi xử lý các văn bản quan trọng, vui lòng giữ lại bản chính và xem xét theo ranh giới và các mục chấp nhận trong văn bản.

Làm cách nào để trích xuất PDF có chú thích trước khi bàn giao? Một câu kết luận

Hãy coi văn bản và chú thích là hai luồng dữ liệu độc lập và trích xuất chúng một cách riêng biệt, đồng thời thực hiện đánh giá bảo mật rõ ràng đối với nội dung chú thích.

hoàn cảnh của bạnCác phương pháp được đề xuấtlý do
Chỉ sử dụng get_text() để xuất văn bảnĐừng coi nó là trọn vẹnĐầu ra mặc định thường không chứa chú thích
Ý kiến sửa đổi của người phản biện cần được giữ lạiLặp lại các chú thích riêng lẻ bằng page.annots()Chú thích là các đối tượng độc lập được đính kèm vào trang
Các bình luận có thể chứa số ID và mã nội bộ.Khớp theo quy tắc nhạy cảm, đánh dấu redacted=True và thay thế bằng trình giữ chỗGhi chú đánh giá có thể chứa dữ liệu nhạy cảm
Trang được xoayĐầu tiên sử dụng page.rotation_matrix hoặc page.derotation_matrix để chuyển đổi tọa độHình chữ nhật chú thích dựa trên trang chưa được xoay
Sẵn sàng cho quá trình dịch thuậtTrước tiên hãy làm sạch các thẻ văn bản đa dạng thức, sau đó kiểm tra thủ công sau khi dịchTránh các bản dịch có chứa mã

Tại sao chú thích lại độc lập với lớp dữ liệu của văn bản

Trong đặc tả PDF, luồng nội dung trang (Luồng nội dung) và từ điển chú thích (Annots Array) được tách biệt về mặt cấu trúc. Phần thân bao gồm các hướng dẫn hiển thị văn bản; chú thích là các đối tượng độc lập được gắn vào trang, có tọa độ, loại và thuộc tính nội dung riêng. Phương thức Page.annots() của PyMuPDF trả về một trình tạo duyệt qua danh sách chú thích độc lập này thay vì luồng văn bản trang.

Điều này có nghĩa là bạn không thể cho rằng tất cả văn bản bạn nhìn thấy đều có thể được trích xuất theo cùng một cách.

Sự khác biệt giữa chú thích lớp nhãn và lớp nội dung

  • Chú thích thẻ (chẳng hạn như đánh dấu và gạch chân) bản thân nó không chứa văn bản mà chỉ ghi lại vùng (Quads/Rects) tương ứng với văn bản gốc. Văn bản thực chỉ có thể có được bằng cách tra cứu văn bản thông qua tọa độ.
  • Chú thích nội dung (chẳng hạn như ghi chú, văn bản tự do) có chuỗi nội dung riêng và có thể đọc trực tiếp.
  • Nếu bạn đọc trực tiếp annot.info["content"] mà không phân biệt loại, bạn sẽ mất bối cảnh ban đầu được chỉ ra bởi chú thích lớp thẻ hoặc ném ngoại lệ nếu nội dung trống.

Ví dụ tổng hợp: trích xuất theo lớp và chặn thông tin nhạy cảm

Để chứng minh logic xử lý chính xác, chúng tôi đã xây dựng một kịch bản tổng hợp chứa ba chú thích điển hình trong mã. Các thông tin đầu vào sau đây là các mẫu được xây dựng trong mã, không phải từ các tệp khách hàng thực sự và chỉ nhằm mục đích trình diễn giáo dục.

Đầu ra dự kiến chứa ba trường có cấu trúc:

  1. Đoạn văn bản: Chỉ chứa văn bản gốc của trang, không có bất kỳ nội dung chú thích nào.
  2. Danh sách chú thích: Mỗi bản ghi bao gồm loại, vị trí, tác giả, thời gian và nội dung (nếu có).
  3. Dấu bảo mật: Nếu nội dung chú thích khớp với các quy tắc nhạy cảm đặt trước (chẳng hạn như số ID, mã nội bộ), mục nhập sẽ được đánh dấu là redacted=True và nội dung được thay thế bằng phần giữ chỗ.

Ba loại ranh giới cần được bảo vệ

  • Chú thích nội dung trống: Ink (Ink) hoặc chú thích đồ họa do một số trình đọc tạo ra không có thuộc tính văn bản. Việc truy cập trực tiếp vào .info["content"] có thể dẫn đến một chuỗi trống hoặc Không có, mã phải thực hiện kiểm tra phòng thủ và không thể cho rằng tất cả các chú thích đều có văn bản có thể đọc được.
  • Tọa độ trang được xoay: Sau khi trang được xoay 90 độ, hình chữ nhật chú thích vẫn dựa trên trang chưa được xoay. Nếu bạn trực tiếp sử dụng các tọa độ này để cắt hoặc định vị văn bản, vị trí sẽ bị xáo trộn hoàn toàn và việc chuyển đổi tọa độ phải được thực hiện trước tiên.
  • Đối tượng mồ côi: Nếu tài liệu bị đóng hoặc trang được tải lại trong quá trình truyền tải, đối tượng chú thích hiện tại sẽ không hợp lệ ngay lập tức. Tất cả các thao tác đọc phải được hoàn thành trong thời gian tồn tại của một trang.

Triển khai Python: duyệt và xác minh chú thích an toàn

Ví dụ này sử dụng PyMuPDF để xây dựng một tệp PDF thử nghiệm trong bộ nhớ, thể hiện khả năng trích xuất theo cấp bậc và logic che giấu cơ bản. Thư viện phụ thuộc là PyMuPDF (tức là gói pymupdf). Vui lòng chạy nó trong môi trường phụ thuộc bị khóa. Phiên bản cần phải >=1.23.0 để truy cập đầy đủ vào thuộc tính chú thích. Mã này không thực hiện các thao tác mạng hoặc ghi tệp, nó chỉ được sử dụng để thể hiện tính logic.

import fitz  # PyMuPDF
import re

# 合成示例:仅在内存中构造,无需外部文件
def create_sample_pdf():
    doc = fitz.open()
    page = doc.new_page()
    # 插入正文
    page.insert_text((72, 72), "Confidential Project Alpha Report", fontsize=12)
    # 添加便签批注(含敏感信息模拟)
    page.add_text_annot((200, 72), "Reviewer: SSN 123-45-6789 approved.")
    # 添加高亮批注(无自身文本,关联正文)
    highlight = page.add_highlight_annot(fitz.Rect(72, 60, 250, 80))
    # 必须调用update()使info变更生效
    highlight.set_info(title="Editor", content="Check this term")
    highlight.update()
    return doc

def extract_with_safety(page, sensitive_pattern=r"\d{3}-\d{2}-\d{4}"):
    body_text = page.get_text("text")
    annotations = []

    # 显式遍历批注生成器
    for annot in page.annots():
        info = annot.info
        # 防御性获取内容,处理None或空字符串
        content = info.get("content", "") or ""

        # 边界处理:敏感词检测与脱敏
        is_sensitive = bool(re.search(sensitive_pattern, content))
        safe_content = "[REDACTED]" if is_sensitive else content

        annotations.append({
            "type": annot.type[1],
            "author": info.get("title", "Unknown"),
            "content": safe_content,
            "is_redacted": is_sensitive,
            # 注意:此为未旋转坐标系,若页面有旋转需配合rotation_matrix使用
            "rect": list(annot.rect)
        })
    return body_text, annotations

# 执行校验
doc = create_sample_pdf()
page = doc[0]
text, annots = extract_with_safety(page)

assert "SSN 123-45-6789" not in str(annots), "敏感信息未被拦截"
assert any(a["type"] == "Highlight" for a in annots), "标记类批注丢失"
assert len(text.strip()) > 0, "正文提取失败"
print(f"Extracted {len(annots)} annotations safely.")

Về cốt lõi, mã là lập trình phòng thủ: độ tinh khiết của nội dung chú thích không đáng tin cậy và tính toàn vẹn của loại chú thích cũng không được đảm bảo. Câu lệnh assert được sử dụng để xác minh logic dự kiến, nhưng đây chỉ là minh chứng và không thể hiện sự đảm bảo hiệu suất từ đầu đến cuối cho tất cả các biến thể PDF.

So sánh các danh mục chú thích

Loại chú thíchCó mang theo văn bản của riêng bạn hay khôngCách lấy nội dungNhững điểm cần lưu ý khi bàn giao
Đánh dấu, gạch chânKhông, chỉ ghi các khu vực (Quads/Rects)Kiểm tra văn bản bằng tọa độNgữ cảnh văn bản gốc tương ứng cần được giữ lại
Ghi chú, văn bản miễn phíCó, đi kèm với chuỗi nội dung riêngđọc trực tiếpKiểm tra nội dung nhạy cảm
Mực in, đồ họa, con dấuThường không có thuộc tính văn bảnThực hiện cuộc gọi ngắn phòng thủXác nhận thủ công xem đó là chữ ký hay con dấu phê duyệt

Tiêu chí chấp nhận và ranh giới đánh giá thủ công

Trích xuất tự động không thể bao gồm tất cả các trường hợp biên. Bảng sau liệt kê các điểm chấp nhận cần được chú ý trong quá trình chuyển giao, phân biệt giữa phạm vi mà mã có thể xử lý và các tình huống yêu cầu can thiệp thủ công.

Quan sát hiện tượngXử lý cấp mãĐánh giá của con người hoặc ra quyết định
Nội dung bình luận trống nhưng biểu tượng tồn tạiLoại bản ghi là Ink hoặc Stamp, nội dung để trốngXác nhận xem đó là chữ ký hay tem phê duyệt và quyết định có giữ ảnh chụp nhanh hay không
Vị trí nhận xét vượt quá CropBoxTọa độ vẫn hợp lệ nhưng không hiển thị được kết xuấtXác định xem đó có phải là chú thích bị bỏ rơi còn sót lại từ lịch sử hay không, chú thích này thường có thể bị bỏ qua.
Nhận xét văn bản đa dạng thức chứa thẻ HTMLTrích xuất chuỗi gốc, giữ thẻLàm sạch thẻ hoặc chuyển đổi chúng thành văn bản thuần túy trước khi dịch để tránh các bản dịch có chứa mã.
Tên tác giả chú thích bị cắt xénTrích xuất nguyên trạng, không cần phỏng đoán mã hóaKiểm tra siêu dữ liệu của tệp nguồn để xác nhận xem đó có phải là tên của một mã hóa cụ thể không
Chuỗi trả lời lồng nhauPyMuPDF trả về danh sách phẳngXây dựng lại cây hội thoại dựa trên ParentID, nếu không ngữ cảnh sẽ bị mất

Không áp dụng: Giải pháp này không áp dụng cho các tệp PDF được mã hóa mà không cung cấp mật khẩu, các tệp PDF bị hỏng về cấu trúc và các tệp sử dụng tiện ích mở rộng riêng tư không chuẩn để xác định loại chú thích. Trong những trường hợp này, tập lệnh có thể âm thầm bỏ qua hoặc đưa ra ngoại lệ C++ cấp thấp. Ngoại lệ này phải được xác nhận bằng cách mở tệp nguồn theo cách thủ công bằng các công cụ chuyên nghiệp.

Sử dụng danh sách kiểm tra để dịch tài liệu

Trước tiên, hãy xác nhận thứ tự trang, vị trí nguồn và tính toàn vẹn của văn bản, sau đó gửi cùng một mẫu đã được giải mẫn cảm cho quá trình dịch. Sau khi dịch, bạn vẫn cần kiểm tra xem tiêu đề, văn bản và hình minh họa có khớp chính xác hay không. Bạn không thể chỉ kiểm tra xem văn bản có mượt mà hay không.

OmniDoc cung cấp cổng dịch thuật tài liệu đa định dạng và trang web chính thức giới thiệu các chức năng so sánh OCR, bảng thuật ngữ và song ngữ. Nếu nhóm muốn bắt đầu xử lý trực tiếp từ tệp, đường dẫn này có thể được đánh giá bằng các mẫu thực. Vui lòng sử dụng các tệp đã được giải mẫn cảm mà bạn có quyền tải lên và xem lại kết quả theo các mục kiểm tra trong bài viết này. Ở đây không có tuyên bố nào rằng OmniDoc sử dụng các thư viện nguồn mở hoặc thuật toán nội bộ của bài viết này và ví dụ này cũng không thay thế việc kiểm tra hiệu suất sản phẩm.

Tài liệu tham khảo và các bước tiếp theo

  1. Chọn tệp dự án lịch sử có chứa các loại chú thích hỗn hợp.
  2. Chạy tập lệnh xác minh ở trên và đếm tỷ lệ các mục yêu cầu xem xét thủ công.
  3. Nếu tỷ lệ vượt quá mong đợi, hãy thêm bước tiền xử lý vào quy trình chuyển giao thay vì dựa vào các công cụ tiếp theo để đưa ra câu trả lời.

🎯 Phương pháp nào phù hợp với bạn?

Nếu bạn chỉ cần dịch văn bản

Bạn có thể trích xuất trực tiếp văn bản nhưng bạn cần xác nhận xem có thiếu chú thích nào trong nội dung được xuất hay không.

Nếu bạn muốn đưa tài liệu cho người khác để lưu trữ

Đồng thời, giữ nguyên văn bản chính và danh sách chú thích, đồng thời đánh dấu nội dung nhạy cảm là đã được giải mẫn cảm.

Nếu tệp PDF của bạn có các trang được xoay

Đầu tiên thực hiện phép chuyển đổi tọa độ, sau đó sử dụng vị trí chú thích để định vị văn bản.

Nếu tệp bị mã hóa hoặc bị hỏng về mặt cấu trúc

Giải pháp này không thể áp dụng được. Vui lòng sử dụng thủ công các công cụ chuyên nghiệp để mở file nguồn để xác nhận.

❓ Câu hỏi thường gặp (FAQ)

1. Tại sao get_text() không chứa chú thích?

Đầu ra mặc định thường chỉ chứa nội dung trang. Chú thích là các đối tượng độc lập với luồng văn bản trang và cần được duyệt qua riêng biệt thông qua page.annots().

2. Có thể đọc trực tiếp nội dung của tất cả các bình luận không?

không thể. Các chú thích kiểu đánh dấu như đánh dấu và gạch chân không chứa văn bản mà chỉ ghi lại các vùng; Các chú thích bằng mực và đồ họa cũng có thể không có thuộc tính văn bản và yêu cầu phán đoán phòng thủ.

3. Tại sao vị trí của trang bị xáo trộn sau khi xoay?

Hình chữ nhật chú thích dựa trên một trang chưa được xoay. Nếu dùng trực tiếp để định vị văn bản sẽ gây ra lỗi. Trước tiên, bạn cần sử dụng page.rotation_matrix hoặc page.derotation_matrix để chuyển đổi tọa độ.

4. Các câu trả lời lồng nhau có bị mất không?

PyMuPDF trả về một danh sách phẳng và nếu cây hộp thoại không được xây dựng lại dựa trên ParentID thì ngữ cảnh sẽ bị mất.

5. PDF được mã hóa có thể được xử lý bằng tập lệnh này không?

Các tệp PDF được mã hóa và không cung cấp mật khẩu không nằm trong phạm vi của giải pháp này và yêu cầu xác nhận thủ công.

📝 Tóm tắt

Chú thích là một lớp dữ liệu độc lập trong PDF. Trước khi bàn giao, văn bản và chú thích phải được trích xuất riêng biệt và các chú thích phải được xem xét để tìm nội dung nhạy cảm. Các tập lệnh tự động có thể bao gồm các trường hợp phổ biến, nhưng các trường hợp phức tạp và quá trình chấp nhận cuối cùng vẫn cần được thực hiện thủ công.

Thử ngay: Tải tài liệu lên để bắt đầu dịch, giữ nguyên bố cục ban đầu

Cập nhật lúc 2026-11-14