Jump to content

PDF Table Parsing in Mandarin: Difference between revisions

From LemonWiki共筆
mNo edit summary
mNo edit summary
 
Line 216: Line 216:


[[Category: Tool]]
[[Category: Tool]]
[[Category: Pdf]]
[[Category: PDF]]
[[Category: Revised with LLMs]]
[[Category: Revised with LLMs]]

Latest revision as of 15:17, 3 November 2026

PDF 表格解析技術筆記

解析 PDF 表格時,通常無法只依賴 pdfplumber.extract_tables()、Camelot、Tabula 或類似函式庫輸出的原始結果。由於 PDF 主要是以版面配置為核心的格式,而非結構化資料格式,實務上往往需要額外的規則、狀態管理與後處理步驟,才能產出穩定且可用的資料集。

🌐 Switch language: EN, 漢字


不同解析工具的比較[edit]

  1. pdfplumber:需要撰寫程式處理資料。
  2. pdftotext 搭配 -layout 選項:缺點是透過空白字元對齊各欄,而非擷取成真正的結構化表格。
  3. jina.ai 解析工具:缺點是透過空白字元對齊各欄,而非擷取成真正的結構化表格。

1. 術語說明[edit]

解析器(Parser)

parser 是負責解析 PDF 內容,並將其轉換為結構化資料的程式。它通常不只是讀取文字或表格,還需要辨識章節、表格類型、欄位位置、資料列、接續內容,以及來源中繼資料。

資料紀錄(Record)

record 是解析器產出的一筆標準化資料。

PDF 中的一列不一定對應一筆資料紀錄。同一筆紀錄可能分散在多列、跨頁接續,或需要繼承父列的資訊後才算完整。

章節/子章節(Section / Subsection)

section 與 subsection 分別指文件中的章節與子章節。

這些欄位通常用來描述資料的來源脈絡,例如某筆紀錄來自哪個章節或表格區塊。

表格類型(Table Type)

table_type 是由解析器自行定義的表格類型標籤,用來表示目前表格屬於哪一種資料結構。

例如:

  • summary_table:摘要表
  • detail_table:明細表
  • parent_child_table:父子關係表
  • cross_reference_table:交叉參照表
  • unknown_table:未知類型表格

table_type 的用途,是協助解析器判斷應套用哪一組解析規則。

它不是 PDF 的內建欄位,也不是 pdfplumber、Camelot 或 Tabula 會自動提供的資訊。

表格結構定義(Table Schema)

table schema 指特定表格類型的欄位結構與解析規則。

通常包含欄位數量、欄位順序、標準化欄位名稱、欄位別名、必填欄位、允許空值的欄位,以及是否需要特殊的接續處理或父子列處理。

在 PDF 表格解析中,table schema 不一定是資料庫綱要,而是解析器用來對齊與標準化表格資料的一組規則。

欄位對應(Column Mapping)

column mapping 指將 PDF 原始欄位對應至標準化欄位的過程。

例如,不同文件可能使用「項目名稱」、「物件名稱」或「標的名稱」等欄名,但在輸出資料時,都可以統一為 item_name。

別名對應(Alias Mapping)

alias mapping 指欄名別名的對照表。

由於 PDF 表格的欄名經常因版本、格式或填報單位而異,解析器需要將多種欄名對應至同一個標準化欄位。

向下填補(Forward-Fill)

forward-fill 指讓後續資料列繼承前面資料列欄位值的處理方式。

在父子列結構中,父列可能只出現一次,後續子列則省略重複資訊。此時,解析器需要將父列資訊填入各個子列。

父列/子列(Parent Row / Child Row)

parent row 是提供主要分類、群組或摘要資訊的資料列。

child row 是隸屬於某個父列的明細資料列。

PDF 表格經常由父列列出主要資訊,子列則只列出明細項目。如果未處理父子列關係,輸出資料可能會遺失必要的脈絡。

跨頁接續(Cross-Page Continuation)

cross-page continuation 指同一筆資料紀錄被拆開,並接續至下一頁的情況。

名稱、說明文字、分類欄位、備註或其他較長的欄位,都可能發生這種情況。

處理跨頁接續時,需要判斷下一頁的文字是否屬於上一頁尚未完成的紀錄,而非直接將其視為新的資料列。

中繼資料(Metadata)

metadata 指用來描述資料來源與解析狀態的輔助資訊。

常見欄位包括 page、table_index、table_type、section、subsection、source_file、raw_row 與 parse_warning。

中繼資料有助於除錯、稽核、資料溯源與資料品質檢查。

2. 章節辨識需要保留跨頁狀態[edit]

PDF 文件中的章節、子章節與表格分類資訊,不一定會在每一頁重複出現。因此,解析器需要保留目前的 section、subsection 或其他文件層級的脈絡,並在後續頁面沿用。

常見情境包括:

  • 接續頁可能只有表格內容,沒有重複顯示章節標題。
  • 目錄、摘要或說明頁可能同時出現多個章節名稱。如果解析器只檢查頁面是否包含特定關鍵字,就可能誤判頁面所屬章節。
  • 章節標題可能因版面差異而使用不同標點或間距,例如全形或半形括號、頓號、冒號、全形句點或多餘空白。
  • 切換章節、子章節或表格類型時,必須清除上一個表格沿用的狀態,避免將資料錯誤帶入下一個區塊。

建議結合文字位置、標題樣式與上下文狀態來判斷章節,而非只依賴整頁的關鍵字比對。

3. 同一章節可能包含多種表格結構[edit]

同一章節可能包含多種類型的表格。如果解析器只根據章節名稱決定欄位對應方式,就可能造成欄位錯置。

解析每個表格時,解析器應先檢查表頭或前幾列,確認下列資訊:

  • table_type
  • 欄位數量
  • 欄位順序
  • 標準化欄位名稱
  • 是否存在父子列關係
  • 是否需要特殊的接續處理

欄名也可能使用別名、縮寫,或隨文件版本採用不同用語。例如,「項目名稱」、「物件名稱」與「標的名稱」,在不同文件中可能代表相近的欄位。因此,實作時應維護一份別名對照表,將不同欄名統一對應至一致的欄位。

4. 父子列關係需要支援向下填補[edit]

部分 PDF 表格會由父列列出主要資訊,後續子列則只列出明細欄位。例如,父列可能包含主要分類、群組名稱、案件編號或摘要資訊,子列則只列出子項編號、明細名稱或詳細內容。

這類表格需要支援向下填補,讓子列繼承父列的欄位值。

設計時應考量:

  • 父列狀態應依 section、subsection 與 table_type 等脈絡分別管理。
  • 父列狀態可能需要跨頁保留。
  • 不應只使用單一文字欄位作為父列識別依據,因為不同父列可能具有相同或相近的名稱。
  • 回填資料時,至少應考量章節、子章節、表格類型與父列識別碼。

章節或表格改變時,應明確重設父列狀態,避免將上一個表格的資料帶入下一個表格。

5. 跨頁接續不只是處理重複表頭[edit]

PDF 表格跨越多頁時,資料可能以各種方式被拆開。解析器若只處理下一頁重複出現的表頭,通常不足以應付實際文件。

常見的跨頁接續情況包括:

  • 下一頁第一列只包含上一頁某個欄位的後半段內容。
  • 名稱、分類、說明文字或備註被拆到不同頁面。
  • 下一頁開頭先出現多列表頭,接著才延續上一頁尚未完成的紀錄。
  • 同一列同時出現接續文字與新資料列的識別碼。
  • 空白欄被壓縮,導致欄位位置偏移。
  • 表格框線、換行或 OCR 辨識結果,將原本的一列拆成多列。

因此,跨頁處理應保留原始欄位位置,不宜過早移除空白欄。必要時,解析器應結合欄位座標、欄位索引、識別碼格式與前一筆紀錄的狀態,判斷接續片段屬於哪個欄位。

合併接續內容時,也應依文字類型採用不同方式:

  • 中文文字片段通常可以直接串接。
  • 英文文字片段通常需要插入空白。
  • 多值欄位、分類欄位或備註,可能需要保留換行、列舉符號或分隔符號。
  • 數值欄位應避免誤將文字片段串接在一起。

6. 表頭、註解與資料列應分階段辨識[edit]

PDF 表格經常包含表頭、單位說明、註解、小計、總計、頁尾或空白列。如果解析器將所有含有文字的列都視為資料列,就很容易產生錯誤紀錄。

建議將解析流程分成下列階段:

  1. 等待表頭關鍵字出現。
  2. 辨識表頭區域與欄名。
  3. 判斷資料列的起始位置。
  4. 處理一般資料列。
  5. 處理跨頁接續內容。
  6. 排除註解、單位說明、小計、總計與頁尾。
  7. 輸出標準化紀錄。

缺漏欄位可以填入 null。但如果欄位已經偏移,解析器就不能直接依壓縮後陣列的順序套用表格結構定義,否則可能造成整列資料錯置。

7. 中繼資料應儲存在每筆紀錄中[edit]

解析 PDF 表格時,除了擷取資料本身,也應保留來源脈絡。這些中繼資料對除錯、稽核、資料溯源,以及後續的扁平化輸出都很重要。

建議每筆紀錄至少包含:

  • page:頁碼
  • table_index:表格索引
  • table_type:表格類型
  • section:章節
  • subsection:子章節
  • source_file:來源檔案
  • raw_row:原始資料列
  • parse_warning:解析警告

將中繼資料寫入每筆紀錄,有助於在 JSON 扁平化為 CSV、匯入資料庫,或以單筆紀錄傳遞時,避免遺失脈絡。

如果文件本身包含年度、季度、期別、版本、批次或分類資訊,也應明確保留,避免混用不同批次的資料。

8. 實作建議[edit]

PDF 表格解析器可以採用分層設計,將擷取、分類、清理、狀態管理、標準化與驗證分開處理。

建議流程如下:

  1. 從 PDF 擷取文字、表格與座標資訊。
  2. 辨識頁面所屬章節與表格區塊。
  3. 根據表頭關鍵字判斷 table_type。
  4. 套用對應的表格結構定義與欄名別名對照表。
  5. 辨識資料列、父列、子列與接續列。
  6. 管理跨頁狀態、父列狀態與其他文件層級狀態。
  7. 將資料轉換為標準化紀錄。
  8. 加入來源中繼資料。
  9. 執行迴歸檢查與資料品質檢查。
  10. 輸出 JSON、CSV 或可直接匯入資料庫的紀錄。

這種設計可以降低個別規則與特定 PDF 版面過度耦合的風險,也能在文件格式改變時,更容易只調整受影響的部分。