Tôi phải làm gì nếu tôi có thể nhấp vào trang mục lục của tệp PDF nhưng bị mất cấp độ sau khi trích xuất?

Hệ thống phân cấp dấu trang phải được kiểm tra trước khi viết. Mục đầu tiên là một cấp và các mục tiếp theo có thể tăng tối đa một cấp; ví dụ này từ chối các cấp độ bất hợp pháp và số trang nằm ngoài giới hạn, đồng thời không tự động thay đổi cấp độ để giả mạo cấu trúc thư mục. Số trang đánh dấu bắt đầu từ một và chỉ mục trang thường bắt đầu từ số 0.

Trang mục lục của PDF có thể được chuyển hướng bình thường trong trình đọc, nhưng sau khi được trích xuất bằng tập lệnh, thứ bậc có thể bị phẳng, số trang có thể bị đặt sai vị trí hoặc thậm chí chỉ mục có thể bất thường. Loại sự cố này thường gặp khi hợp nhất các tệp được quét hoặc tệp có cấu trúc dấu trang không đều. Nếu kết quả trích xuất được chuyển trực tiếp cho người dùng xuôi dòng thì có thể xảy ra lỗi trong quá trình phân đoạn và liên kết dịch thuật.

Bài viết này dành cho các nhà phát triển và nhóm tài liệu cần xử lý hàng loạt danh mục PDF. Sau khi đọc, bạn có thể hiểu ý nghĩa của giá trị trả về get_toc(), nắm vững các quy tắc xác minh cấp độ và số trang, đồng thời biết tình huống nào nên chuyển sang xác minh thủ công. Bài viết này sử dụng mẫu tổng hợp để minh họa phương pháp xử lý và mã đã được mẫu kiểm tra trong môi trường biệt lập, nhưng điều này không thể hiện sự đảm bảo về tất cả các tệp thực hoặc hiệu ứng 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.

Tôi phải làm gì nếu nhấp vào được trang mục lục PDF nhưng sau khi trích xuất thì hệ thống phân cấp bị mất? Một câu kết luận

Xác minh trước rồi viết: Phải kiểm tra cấp độ dấu trang trước, mục đầu tiên được coi là cấp độ đầu tiên, các cấp độ tiếp theo không được vượt quá mục trước cộng một và các mục có số trang ngoài giới hạn sẽ không được ghi.

hoàn cảnh của bạnCác phương pháp được đề xuấtlý do
Trang thư mục có thể được nhấp vào và hệ thống phân cấp phẳng hoặc bị lệch sau khi trích xuất.Trước tiên, hãy sử dụng get_toc() để lấy danh sách gốc, sau đó xác minh từng danh sách một trước khi sử dụng.Danh sách ban đầu được get_toc() trả về không có xác thực có cấu trúc
Số trang là 0 hoặc vượt quá tổng số trangHủy mục nhập và nhật kýSố trang vượt quá giới hạn sẽ gây ra lỗi nhảy
get_toc() trả về danh sách trốngThay vào đó hãy sử dụng phân tích bố cục văn bản và đừng thử lại một cách mù quángTệp có thể không được nhúng siêu dữ liệu dấu trang
Tiêu đề giống nhau tương ứng với nhiều số trang khác nhauĐánh dấu là không rõ ràng, chuyển sang xác minh thủ côngKhông thể tự động xác định số trang nào là chính xác

Tại sao kết quả trích xuất lại bị mất cấp?

get_toc() mặc định xuất ra danh sách các bộ ba [level, title, page]. Trong số đó, page là số trang vật lý bắt đầu từ 1 và level chỉ thể hiện độ sâu lồng nhau và không đảm bảo tính liên tục hoặc tính hợp pháp.

Nếu tệp PDF nguồn được tạo bằng công cụ kết hợp quét thì các vấn đề thường gặp bao gồm:

  • Nhảy cấp: Ví dụ: nhảy trực tiếp từ 1 lên 3
  • Ngoại lệ về số trang: Số trang bằng 0 hoặc vượt quá tổng số trang
  • Ngoại lệ tiêu đề: Tiêu đề chứa các ký tự điều khiển

Nếu sử dụng trực tiếp cho các tác vụ xuôi dòng sẽ gây nhầm lẫn trong các đoạn dịch hoặc lỗi liên kết. Nguy hiểm hơn, một số tệp PDF có trang mục lục trực quan nhưng không có siêu dữ liệu dấu trang được nhúng. Việc get_toc() trả về một danh sách trống vào thời điểm này là điều bình thường và cần phải sử dụng phân tích bố cục văn bản để thay thế.

Ví dụ về bố cục khép kín

Xem danh sách nhập để biết các phụ thuộc ví dụ. Mã xây dựng đầu vào trong bộ nhớ và các bản ghi lần chạy được cung cấp riêng và không thể hiện sự đảm bảo về tất cả các tệp thực.

import pymupdf
def validate(rows, pages):
    previous = 0
    for level, title, page in rows:
        if type(level) is not int or level < 1 or level > previous + 1:
            raise ValueError("invalid hierarchy")
        if type(page) is not int or not 1 <= page <= pages:
            raise ValueError("invalid destination")
        if not isinstance(title, str) or not title.strip():
            raise ValueError("empty title")
        previous = level
    return rows
with pymupdf.open() as doc:
    for _ in range(3):
        doc.new_page()
    rows = [[1, "Chapter", 1], [2, "Section", 2], [1, "Appendix", 3]]
    doc.set_toc(validate(rows, doc.page_count))
    assert doc.get_toc() == rows
    assert len(doc.get_toc()) == 3
    for bad in [[[2, "Bad", 1]], [[1, "Bad", 99]], [[1, "", 1]]]:
        try:
            validate(bad, doc.page_count)
        except ValueError:
            pass
        else:
            raise AssertionError("invalid outline accepted")

Quy tắc xử lý đầu vào hợp pháp và bất hợp pháp

Dữ liệu nhập đúng phải đáp ứng: danh sách các bộ ba có mức liên tục và số trang trong phạm vi [1, doc.page_count]. Ví dụ: [[1, "引言", 1], [2, "背景", 2], [1, "方法", 5]] là hợp pháp, cấp độ thứ hai xuất hiện sau cấp độ đầu tiên và tuân theo cú pháp phác thảo PDF.

Thông tin đầu vào không chính xác thường gặp bao gồm:

  • Cấp độ là 0 hoặc âm
  • Số trang là 0
  • Số trang vượt quá tổng số trang
  • Tiêu đề là chuỗi rỗng hoặc chỉ chứa ký tự khoảng trắng

Đối với những tình huống này, các phương pháp được đưa ra trong bài viết như sau:

  1. Bỏ qua các mục có số trang không hợp lệ và ghi lại cảnh báo.
  2. Giữ các phần giữ chỗ như [untitled] cho các tiêu đề trống để duy trì tính toàn vẹn về cấu trúc.
  3. Không làm gián đoạn quá trình phân tích toàn bộ thư mục chỉ vì một lỗi duy nhất.

Đối với trường hợp cấp độ nhỏ hơn 1, có hai chiến lược cần lưu ý: phần tóm tắt của ví dụ chủ trương bác bỏ các cấp độ bất hợp pháp và không tự động sửa chúng, trong khi mô tả quy tắc trong bài viết là buộc nó về 1. Hãy quyết định giữa hai chiến lược theo quy trình của bạn. Cũng lưu ý rằng các quy tắc này được thiết kế để đảm bảo tính mạnh mẽ của các quy trình tiếp theo và không phải là yêu cầu bắt buộc của tiêu chuẩn PDF. Thử nghiệm thực tế cho thấy khi số trang vượt quá ranh giới, PyMuPDF sẽ in cảnh báo nhưng không đưa ra ngoại lệ. Vì vậy, chức năng xác minh phải chủ động lọc và không thể dựa vào hành vi của thư viện.

📊 So sánh cốt lõi

Trong các tình huống tài liệu khác nhau, kết quả và phương pháp xử lý được đề xuất của get_toc() là khác nhau:

Tài liệukết quả get_toc()Khuyến nghị sử dụng
Đã đánh dấu trang và hợp pháp về cấu trúcTrả về danh sách bộ baSử dụng trực tiếp sau khi xác minh
Có dấu trang nhưng thứ bậc hoặc số trang không bình thườngTrả về danh sách các ngoại lệLọc và ghi nhật ký, đồng thời chuyển sang lao động thủ công khi cần thiết
Phiên bản trực quan có trang mục lục nhưng không có dấu trangQuay lại danh sách trốngChuyển sang phân tích bố cục văn bản
Sắp xếp lại các tài liệu như EPUBĐịnh dạng số trang là (chương, pno)Logic xác minh số trang này không áp dụng và cần xử lý chuyên dụng

Tiêu chí chấp nhận và ranh giới kiểm tra thủ công

Bảng dưới đây chỉ tập trung vào giai đoạn trích xuất siêu dữ liệu danh mục PDF:

Quan sát hiện tượngQuyết định xử lý vụ việcLiệu tự động hóa có phù hợp hay không
Số trang bằng 0 hoặc lớn hơn tổng số trangLoại bỏ mục nhập và ghi lạiĐúng vậy
Các cấp nhỏ hơn 1 hoặc không phải số nguyênXử lý theo các quy tắc trên (xem giải thích trước)Đúng vậy
Tiêu đề hoặc hoàn toàn trống rỗng hoặc chỉ mang tính biểu tượngThay thế bằng [untitled]Đúng vậy
Các cấp độ nhảy (ví dụ: 1 đến 3)Giữ lại các lớp gốc mà không tô đầy các lớp giữaCó (hợp pháp về cấu trúc)
Cùng một tiêu đề tương ứng với nhiều số trang khác nhauĐánh dấu là mơ hồ, chuyển sang thủ côngKhông
Hơn 200 bài viết mà không có thay đổi về cấp bậcNghi ngờ nhận dạng sai OCR cần xác minh thủ côngKhông
Bao gồm các hành động URI hoặc JavaScript bên ngoàiLọc các chuyển hướng không phải trangCó (Chính sách bảo mật)
Sắp xếp lại các tài liệu như EPUB, số trang (chương, pno)Logic xác thực số trang này không áp dụngKhông (cần được đối xử đặc biệt)

Lưu ý rằng phần trình diễn mã chỉ kiểm tra tính hợp pháp của cấu trúc; hiệu ứng đầu cuối cũng cần được kết hợp với render để xác minh độ chính xác của các bước nhảy.

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

Nếu bạn cần trích xuất thư mục theo lô

Đầu tiên, thực hiện xác thực cấu trúc kết quả của get_toc(), sau đó ghi chúng vào các quy trình làm việc tiếp theo và lưu nhật ký để xác minh.

Nếu PDF của bạn có mục lục trực quan nhưng được trích xuất trống

Đừng thử lại get_toc(); chuyển sang phân tích và xử lý bố cục văn bản.

Nếu mục thư mục của bạn có cùng tên nhưng khác trang

Xác minh thủ công các mục này; không tự động chọn một trong các số trang.

Nếu bạn muốn giao tài liệu cho quá trình dịch thuật,

Đầu tiên, hãy xác nhận cấu trúc mục lục và số trang chính xác trước khi dịch để tránh nhầm lẫn giữa các đoạn.

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

1. Tại sao số trang bắt đầu từ 1, trong khi chỉ mục trang thường bắt đầu từ 0?

Số trang đánh dấu là số trang vật lý bắt đầu từ 1, trong khi chỉ mục trang trong các thư viện như PyMuPDF thường bắt đầu từ 0. Sự khác biệt này rất quan trọng khi chuyển đổi, nếu không số trang có thể bị lệch.

2. get_toc(): Việc trả về một danh sách trống có nhất thiết chỉ ra vấn đề về tệp không?

Không hẳn vậy. Một số PDF có trang mục lục trực quan nhưng không có siêu dữ liệu dấu trang nhúng, nên việc trả về danh sách trống là bình thường. Trong trường hợp này, nên sử dụng phân tích bố cục văn bản thay thế.

3. Nếu số trang vượt quá giới hạn, thư viện có báo lỗi ngay lập tức không?

Không. Các bài kiểm tra trong bài viết này cho thấy PyMuPDF in cảnh báo khi số trang ra ngoài ranh giới nhưng không ném ngoại lệ, vì vậy hàm xác thực phải chủ động lọc.

4. Các bước nhảy theo thứ bậc (như đi thẳng từ 1 lên 3) có cần phải lấp đầy các lớp giữa không?

Đề xuất trong bài viết là giữ nguyên hệ thống phân cấp ban đầu và không lấp đầy các lớp giữa, vì cấu trúc này vẫn hợp pháp.

📝 Tóm tắt

Cấu trúc phân cấp và số trang của thư mục PDF cần được kiểm tra trước khi sử dụng, vì vậy kết quả gốc của get_toc() không thể được coi là cấu trúc đáng tin cậy trực tiếp. Khi gặp phải sự mơ hồ hoặc thiếu dấu trang, hãy nhanh chóng chuyển sang lao động thủ công hoặc chuyển sang các phương pháp khác để tránh lỗi quy trình sau.

Trải nghiệm ngay: Tải lên tài liệu của bạn để bắt đầu dịch, giữ nguyên định dạng gốc

Tham khảo và các bước tiếp theo

Bước tiếp theo là chuẩn bị một file PDF thử nghiệm chứa các vấn đề thư mục đã biết, chạy script xác minh trên và tính toán tỷ lệ các bất thường khác nhau. Nếu thường xuyên có các lần bỏ qua phân cấp hoặc lệch số trang, hãy cân nhắc thêm bước tái tạo mục lục trước khi dịch.

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

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

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

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