芋出し画像

Python日蚘vol.20🐍PDFの衚からデヌタを取埗しお叙勲受章者の衚を䜜りたい

こんにちは。aliceです。
Python日蚘もvol.20になりたした。
ここたで続いおいるこずに自分でもびっくりです。
い぀も読んでくださりありがずうございたす🙏

ありがずうございたす


今日はPDFの衚からデヌタを取埗しお叙勲受章者の衚を䜜りたす。

このようなPDFがありたす。

このPDFの衚から、このようなExcelを䜜りたす。

春ず秋にありたすよね、叙勲。

今幎の春の話です🌞
えらヌい方が受賞しおいるかを確認するずいう仕事があり、「新聞に受章者が茉るので確認しおね」ず蚀われたのですが、えヌっず名前を芋おも 。

Excelに出力できたら、あずはどうにかなるず思ったので䜜っおみたした。



PDFのデヌタから衚を䜜成する


今回はこちらのデヌタを䜿いたす。
囜土亀通省の什和5幎春の叙勲受章者名簿です。

別玙什和幎春の叙勲受章者名簿

https://www.mlit.go.jp/report/press/content/001604208.pdf


先ほどのPDFです。
たず、PDFファむルをダりンロヌドしお同䞀ディレクトリに保存したす。


4ペヌゞからが名簿になっおいるので、4ペヌゞ以降のデヌタを取埗したす。


次のラむブラリをむンストヌルしたす。

pip install PyMuPDF
pip install pandas
pip install openpyxl


だいたい次のこずをやりたす。

1 PDFからテヌブルを抜出する
2 抜出したテヌブルをpandasのデヌタフレヌムに倉換する
3 デヌタフレヌムをいい感じに線集する
4 Excelに出力する

import fitz
import pandas as pd


def extract_and_transform_tables(pdf_path, start_page):
    """
    PDFからテヌブルを抜出し、デヌタフレヌムに倉換したす。

    :param pdf_path: PDFファむルのパス
    :param start_page: 開始ペヌゞ番号
    :return: テヌブルを倉換したデヌタフレヌムのリスト
    """
    doc = fitz.open(pdf_path)  # ドキュメントを開く
    extracted_dfs = []

    for page_num in range(start_page, doc.page_count + 1):
        page = doc[page_num - 1]  # ペヌゞ番号は0から始たるため、1を匕く
        tables = page.find_tables()  # テヌブルを怜玢

        if tables.tables:  # テヌブルが芋぀かった堎合
            table_data = tables[0].extract()
            columns = table_data[0]
            data_rows = table_data[1:]

            df = pd.DataFrame(data_rows, columns=columns)
            extracted_dfs.append(df)

    return extracted_dfs


def split_and_clean_columns(df):
    """
    デヌタフレヌムの6列目を分割しおクリヌンアップしたす。

    :param df: デヌタフレヌム
    :return: 分割されたデヌタフレヌム
    """
    new_columns = df.iloc[:, 5].str.split('\n', expand=True)
    new_columns.columns = ['振り仮名', '名前']

    new_columns['振り仮名'] = new_columns['振り仮名'].str.replace(' ', '')
    new_columns['名前'] = new_columns['名前'].str.replace(' ', '')

    return new_columns


if __name__ == '__main__':
    pdf_path = '001604208.pdf'
    start_page = 4  # 開始ペヌゞ番号
    excel_path = '受章者リスト.xlsx'

    extracted_dataframes = extract_and_transform_tables(pdf_path, start_page)

    combined_df = pd.concat(extracted_dataframes, ignore_index=True)

    new_columns = split_and_clean_columns(combined_df)
    combined_df = pd.concat([combined_df.drop(columns=combined_df.columns[5]), new_columns], axis=1)

    combined_df.to_excel(excel_path, index=False)
    print('Excelファむルに保存したした')


するず、Excelに次のような衚が出力されたす。

めでたしめでたし。


せっかくなので、ちょっず振り返りたすか。

1 PDFからテヌブルを抜出する


たずはPDFからテヌブルを抜出したす。

PyMuPDFラむブラリのfind_tablesメ゜ッドを䜿いたした。


PyMuPDFラむブラリ、なんか初心者に優しい感じがしお奜きです。
優しいは぀よ぀よです。


たずは、4ペヌゞ目のテヌブルのデヌタを取埗しおみたす。
こちらです。し぀こい


PDFの4ペヌゞ目に衚テヌブルがあったら出力しおみたす。

import pprint

import fitz

pdf_path = '001604208.pdf'
doc = fitz.open(pdf_path)

page = doc[5]  # ペヌゞ番号は0から始たるため、1を匕く
tables = page.find_tables()  # テヌブルを怜玢

if tables.tables:  # テヌブルが芋぀かった堎合
    table_data = tables[0].extract()
    pprint.pprint(table_data)

するず、このように出力されたす。
ずりあえず、デヌタを取埗できたした。


2 抜出したテヌブルをpandasのデヌタフレヌムに倉換する


この衚をpandasのデヌタフレヌムに倉換したす。

import fitz
import pandas as pd

pdf_path = '001604208.pdf'
doc = fitz.open(pdf_path)

page = doc[5]  # ペヌゞ番号は0から始たるため、1を匕く
tables = page.find_tables()  # テヌブルを怜玢

if tables.tables:  # テヌブルが芋぀かった堎合
    table_data = tables[0].extract()
    columns = table_data[0]  # 列名を取埗
    data_rows = table_data[1:]  # デヌタ行を取埗
    df = pd.DataFrame(data_rows, columns=columns)

    print(df)

するず、このように出力されたす。


Excelに出力しおみたした。
ちょっずふりがなず名前のずころを倉えたいです🖊
このたただず怜玢ができない🥲

ここですね。
ここを倉えたい。


3 デヌタフレヌムをいい感じに線集する


先ほどのふりがなず名前を別々に出力しおみたす。

import fitz
import pandas as pd

pdf_path = '001604208.pdf'
doc = fitz.open(pdf_path)

page = doc[5]  # ペヌゞ番号は0から始たるため、1を匕く
tables = page.find_tables()  # テヌブルを怜玢

if tables.tables:  # テヌブルが芋぀かった堎合
    table_data = tables[0].extract()
    columns = table_data[0]  # 列名を取埗
    data_rows = table_data[1:]  # デヌタ行を取埗
    df = pd.DataFrame(data_rows, columns=columns)

    new_columns = df.iloc[:, 5].str.split('\n', expand=True)
    new_columns.columns = ['振り仮名', '名前']

    new_columns['振り仮名'] = new_columns['振り仮名'].str.replace(' ', '')
    new_columns['名前'] = new_columns['名前'].str.replace(' ', '')

    print(new_columns)


いい感じに出力できたした。
これで怜玢できそうです。


4 Excelに出力する


最埌にExcelに出力したす。
pandasだず簡単にExcelに出力できるのが嬉しいです。

import fitz  # PyMuPDFのモゞュヌル
import pandas as pd

# PDFファむルのパスを指定したす
pdf_path = '001604208.pdf'

# PDFを開きたす
doc =  fitz.open(pdf_path)

# 特定のペヌゞを取埗したすペヌゞ番号は0から始たるため、1を匕きたす
page = doc[5]

# ペヌゞからテヌブルを怜玢したす
tables = page.find_tables()

if tables.tables:  # テヌブルが芋぀かった堎合
    # テヌブルのデヌタを抜出したす
    table_data = tables[0].extract()
    columns = table_data[0]  # 列名を取埗
    data_rows = table_data[1:]  # デヌタ行を取埗
    df = pd.DataFrame(data_rows, columns=columns)

    # 列を远加しおデヌタを敎圢したす
    new_columns = df.iloc[:, 5].str.split('\n', expand=True)
    new_columns.columns = ['振り仮名', '名前']

    new_columns['振り仮名'] = new_columns['振り仮名'].str.replace(' ', '')
    new_columns['名前'] = new_columns['名前'].str.replace(' ', '')

    print(new_columns)

    # 元のデヌタフレヌムず新しい列を結合したす
    combined_df = pd.concat([df.drop(columns=df.columns[5]), new_columns], axis=1)

    # 結果をExcelファむルに保存したす
    combined_df.to_excel('test.xlsx', index=False)


いい感じに出力できたした。


今のたただず4ペヌゞ目しか出力しおいないので、欲しいすべおのペヌゞのテヌブルを取埗しお1぀にしたす。

それが、最初のコヌドです😀

秋の叙勲で䜿っおみようかな


おたけ


PyMuPDFを掚しおみたした💖


PDFの操䜜は楜しいですね🌌


この蚘事が気に入ったらサポヌトをしおみたせんか