PythonでPDF表を抽出する方法


皆さん、こんにちは、PDFから情報を引き出すのはオフィスシーンでよく使われる操作です。また、よく読者が楽屋で聞く操作です。
内容が少ない場合は手動でコピーして貼り付けできますが、大量に抽出する必要があればPythonを使ってもいいです。以前にも関連記事を転載しました。主にpdfplumberライブラリを使っています。今日はもう一度例を挙げて説明します。
通常PDFの表はピクチャーとテキストタイプに分けられます。テキスト型にはシンプルと複雑があります。本文はこの三つの部分について例を挙げて解説する。
  • シンプルなテーブルを抽出する
  • より複雑なテーブルを抽出する
  • 画像型テーブルを抽出する

  • 使うモジュールは主にあります。
  • pdfplumber
  • パンdas
  • Tesseract
  • PIL
  • 本文に出てくるPDF材料は、巨潮情報公式サイトでダウンロードした公開PDFファイルで、テーマは投資信託に関するもので、関連情報などは以下の通りです。

    内容は全部で6ページで、後文の例が展示されます。
    一、簡単なテキストタイプのデータ
    簡単なテキストタイプの表はPDFのページに一つの表しかありません。表の内容は完全にコピーできます。例えば、私達が選択した内容はPDFの第四ページです。内容は以下の通りです。

    このページは一つの表しかありません。これをExcelに書き込みます。まずコードを入れます。
    
    import pdfplumber as pr
    import pandas as pd
    pdf = pr.open('                     .PDF')
    ps = pdf.pages
    pg = ps[3]
    tables = pg.extract_tables()
    table = tables[0]
    print(table)
    df = pd.DataFrame(table[1:],columns = table[0])
    for i in range(len(table)):
        for j in range(len(table[i])):
            table[i][j] = table[i][j].replace('
    ','') df1 = pd.DataFrame(table[1:],columns = table[0]) df1.to_excel('page2.xlsx')
    得られた結果は以下の通りです。

    PDFの上原表と比較すると、内容は完全に一致していますが、唯一の違いは主要業務の内容が多いため、表示の不備が生じています。
    まず使用する2つのライブラリを導入します。pdfplumberでは、オプン関数はPDFファイルを開くために使用され、コードは相対パスを使用しています。open().pagesはPDFのページ数を取得し、印刷ps値は以下の通りとする。

    pg=ps[3]は私たちが選んだ第三ページを表しています。
    pg.extract_テーブル():すべてのテーブルを出力し、ネスティングリストを返します。その構造レベルはテーブル→row→セルです。このとき、ページ上の表全体が大きなリストに入れられ、元の表の各行がその大きなリストの各サブリストを構成します。単一の外殻リスト要素を出力する場合、元の表の同じ行の要素からなるリストが得られます。
    似ているのはpg.extract_です。テーブル():複数の独立リストを返し、その構造レベルはrow→cellです。ページ内に同じ行数のテーブルが複数存在する場合、上位テーブルはデフォルトで出力されます。そうでないと、一番多い行の表しか出力されません。このとき、表の各行は個々のリストとして機能し、各要素は元の表の各セルの内容となります。
    このページにはテーブルしかないので、テーブルセットの最初の要素が必要です。テーブルの値を印刷します。

    上記では不要な文字が存在していますが、その役割は改行ですが、Excelでは必要ありません。これを削除する必要があります。コードの中のforサイクルとreplace関数で制御をスペースに置き換えます。テーブルの観察は2つの要素が入ったリストです。
    最後のdf 1=pd.DataFrame(table[1:)、columns=table[0]というコードの役割は、データボックスを作成し、対応する列にコンテンツを配置することです。
    このコードは簡単にExcelにデータを入れます。さらにスタイルを調整する必要があれば、openpyxlなどのモジュールを使って修正できます。
    二、複雑型表抽出
    複雑な表とは、表のスタイルが統一されていないか、またはページに複数の表があります。PDFの5ページ目を例に挙げてください。

    このページには大きな表が二つあります。詳しく見ると、実は4つの表です。簡単な表の種類によって方法を抽出して、得られた効果は以下の通りです。

    すべての表のテキストを抽出するだけで、実際には最初の表は二つの表に細分化されているので、さらに修正して、この表を再び分割する必要があります。上半分のコードを抽出すると以下のようになります。
    
    import pdfplumber as pr
    import pandas as pd
    pdf = pr.open('                     .PDF')
    ps = pdf.pages
    pg = ps[4]
    tables = pg.extract_tables()
    table = tables[0]
    print(table)
    df = pd.DataFrame(table[1:],columns = table[0])
    for i in range(len(table)):
        for j in range(len(table[i])):
            table[i][j] = table[i][j].replace('
    ','') df1 = pd.DataFrame(table[1:],columns = table[0]) df2 = df1.iloc[2:,:] df2 = df2.rename(columns = {"2019 12 31 ":"2019 1-12 ","2020 9 30 ":"2020 1-9 "}) df2 = df2.loc[3:,:] df1 = df1.loc[:1,:] with pd.ExcelWriter(' .xlsx') as i:     df1.to_excel(i,sheet_name=' ', index=False, header=True) #     df2.to_excel(i,sheet_name=' ',index=False, header=True) #
    このコードは簡単な表から抽出した上で修正されました。14行目のコードの役割は他のヘッダの情報を抽出してdf 2に値を付けてからdf 2に名前を変更することです。
    印刷df 2は、columns列名と第一行情報が重複していることが分かります。したがって、先ほどのステップを繰り返して、loc関数を使ってデータボックスを切断する必要があります。
    ここでは珍しいパンdas.Excerwriter関数セットforサイクルを使っていますが、これは直接書き込みによる最後のデータが元のデータを覆うのを避けるためです。興味があります。withopenを使わない方法を試してみてください。最終的に得られた効果は以下の通りです。


    今この表は二つのsheetにおいて単独で展示されています。もちろん比較用に一枚の表に置いてもいいです。

    結局複雑なタイプの表の主観は非常に大きいです。状況によって違う処理が必要です。一苦労永逸の方法を書くのは難しいです。
    三、画像タイプ表の抽出
    最後に最も処理が難しいのがピクチャータイプの表で、よくある人はどのようにピクチャー型のPDFの中のフォーム/テキストなどの情報を抽出するかを聞きます。
    本質的には写真を抽出して、その後どのように画像に対して情報を抽出するかはPythonがPDF表を抽出するというテーマとあまり関係がありません。
    ここでは簡単に紹介します。つまり、まず写真を取ってからOCRの識別抽出表を行います。PythonではTesseractライブラリが使えます。まずpipのインストールが必要です。
    
    pip install pytesseract
    Pythonでこのライブラリをインストールした後、私達はexeファイルをインストールして、後のコードで使います。
    
    http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe
    インストールが完了したら大丈夫です。正常な手順でインストールすれば中国語が認識されないので、簡体字中国語のパケットをインストールしてください。ダウンロードアドレスはhttps://github.com/tesseract-ocr/tessdata/find/master/chi_sim.trineddataです。Tesseract-OCRのtessdataディレクトリの下に置いてもいいです。
    次に簡単な画像タイプのpdfを使います。

    最初のステップは、画像を抽出し、ここでGUIオフィスオートメーションシリーズの画像抽出ソフトを使用して、PDF中の画像を抽出し、次のような画像を得る。

    次に、下のコード識別画像の内容を実行します。
    
    import pytesseract
    from PIL import Image
    import pandas as pd
    pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)/Tesseract-OCR/tesseract.exe'
    tiqu = pytesseract.image_to_string(Image.open('   .jpg'))
    print(tiqu)
    tiqu = tiqu.split('
    ') while '' in tiqu:    # for   tiqu.remove('')   first = tiqu[:6]   second = tiqu[6:12]   third =  tiqu[12:]   df = pd.DataFrame()   df[first[0]] = first[1:]   df[second[0]] = second[1:]   df[third[0]] = third[1:] #df.to_excel(' .xlsx')  # xlsx
    私達の考えはTesseract-OCRで画像を解析し、文字列を得て、文字列に対してsplit関数を使い、文字列をリストに変えて同時に削除します。
    続いて、私たちのリストにはスペースがあります。ここでは、whileループでこれらの空の文字を削除します。ここではforループは使えません。削除するたびに、リストの中の要素は一つ前に進みます。このように削除が不完全です。最後にパンdasでこれらをデータボックス形式にします。最終的に得られた効果は以下の通りです。

    この画像型テーブルの内容は完璧に解析され、処理されていることが分かります。もちろん簡単に解決できる原因もこの表の十分な簡単さと関係があります。実際のシーンの中の写真はもっと複雑な妨害要素があるかもしれません。これはみんなで処理しながら自分で一番適切な方法を見つけなければなりません。
    以上はPythonでPDF表を抽出する方法の詳細です。PythonについてPDF表を抽出する資料は他の関連記事に注目してください。