PDFから表情報を抽出する

メソ
2025-01-24
2025-01-24

業務でPDFに記載されている情報をExcelに抽出することになりました。
ページ数は多くないもののコピーができなかったため、PythonのPyMupdfライブラリを使用して情報の抽出を試します。

PDFとは

PDFとは「Portable Document Format(ポータブル・ドキュメント・フォーマット)」の略で、アドビが開発したファイル形式です。
引用元 : https://www.adobe.com/jp/acrobat/roc/blog/about-pdf.html

特長としてはフォーマットが変更されても同じようにデータを閲覧することが出来る、変更や追記が容易にできない、などが挙げられます。
PDFデータは表示上では文字情報等が並んでいますが、中身としてはバイナリデータで構成されており、独自の方式で記述されています。

今回はPyMupdfライブラリを用いて、文字や表情報を抽出してみます。

文字の抽出

PDF上の文字を取得し、TXTファイルに保存します。

import pymupdf
 
pdf = pymupdf.open("test.pdf")
output = open("test.txt","wb")
 
for page in pdf:
    text = page.get_text().encode("utf8")
    output.write(text)
    output.write(bytes((12,)))
output.close()

思ったより短い行数で情報を取得することが出来ました。
ただ、今回は主に表情報を取得したいため、次項で表の抽出を進めていきます。

複数ページの読み込みと表の抽出

業務で利用したPDFファイルは1ファイルあたり3ページほどあり、その中に複数の表が含まれていました。
ここではページ上にある表の読み込みを3ページで全てで行い、Excelに転記していきます。

なお、PDFに記載されている表のイメージは以下のようになります。

Title 挨拶
FlowA おはよう
FlowB こんにちは
FlowC こんばんは

処理内容としては、

  1. ページを読み込む
  2. ページ上にある表を読み込む
  3. 表にある項目を抽出する

を全てのページで繰り返し、1表あたりの情報を1行としてExcelに転記していきます。

from pprint import pprint
import pandas as pd
import openpyxl
import pymupdf

excel_path = "output.xlsx"
doc = pymupdf.open("test.pdf")
start_row = 0
page_max = doc.page_count
all_data = pd.DataFrame(columns=['Title','FlowA','FlowB','FlowC'])
 
#ページの読み込み
for pages in range(page_max):
  page = doc[pages]
  table = page.find_tables()
  if table.tables:
    table_max = len(table.tables)

    #表の抽出
    for table_num in range(table_max):
       table_elm = table[table_num].extract()
       ar = []
 
       #項目の抽出
       for col_num in range(4):
        if len(table_elm) > col_num and len(index[col_num]) > 1:
          col = table_elm[col_num][1]
          ar.append(col)
       if len(ar) == 4:
        all_data.loc[len(all_data)] = ar
 
#Excelへの記載
with pd.ExcelWriter(excel_path, mode='a', engine='openpyxl', if_sheet_exists='overlay') as writer:
  all_data.to_excel(writer, sheet_name='Sheet1', index=False, header=False if start_row > 0 else True, startrow=start_row)

とりあえず取得した表を追記することができました。
ページを跨いだ表に対して正しく出力されるところまではたどり着けず、今回はタイムアップになりました。余裕があればまたチャレンジしてみたいと思います。

参考

すべてのドキュメントテキストを抽出する方法

ページからのテーブルの抽出