【Python】PdfReadError:EOF marker not foundの解決方法(PyPDF2)

時計 2021.01.28 / 時計

【Python】PdfReadError:EOF marker not foundの解決方法(PyPDF2)

本記事ではPythonプログラムで発生する、PdfReadErrorEOF marker not foundの解決方法について解説していきます。

エラーは以下のように表示されます。

エラー

raise utils.PdfReadError("EOF marker not found")

PdfReadError: EOF marker not found

このエラーはPDF操作を行った際に発生することがあるエラーです。
私の場合はPDF内のテキストを読み取るプログラムを実行したときにこのエラーが発生しました。

このエラーの意味や解決方法を見ていきましょう。

本記事を通して以下の知識を学べます。

学べる知識
  • EOF marker not foundについて
  • EOFの知識
  • EOF marker not foundの解決方法

エラー発生時のプログラム

プログラム内容

PDFのテキストを読み取るプログラムを実行した際に、EOF marker not foundエラーが発生しました。

モジュールにはPyPDF2を使用しました。
PyPDF2の詳しい使い方については以下記事をご参照ください。

問題なくPyPDF2を組み込んだプログラムでPDFのテキスト読み取りができていましたが、特定のPDFだけEOF marker not foundエラーが発生しました。

プログラムのソース

PdfReadErrorが発生した、PDFのテキスト読み取りスクリプトのソースを以下に記します。

import PyPDF2

file = open('pdf.pdf', 'rb')
reader = PyPDF2.PdfFileReader(file)
print(reader.numPages)
page = reader.getPage(0)
text = page.extractText()
print(text)

エラー解析

PdfReadErrorとは

PDF関連のエラーには大きく2種類あります。
警告(PdfReadWarning)とエラー(PdfReadError)です。

警告(PdfReadWarning)はPDFの構文使用の不備などで発生します。

エラー(PdfReadError)はフォントのエンコード不一致などで発生します。
本記事のエラーはこのPdfReadErrorです。

EOFとは

今回のエラーはEOF marker not foundです。日本語だと「EOFマーカーが見つからない」という意味です。

ではEOFとは何なのか。

EOFとはPDFデータの終端を表す文字列であり、PDFデータの終端に位置します。

%%EOFという文字列でPDFデータに記述されています。

このPyPDF2.utils.PdfReadErrorを例外処理で検知することで、PDFかどうかの判別をすることもできます。

解決方法

もっともベストな解決方法はEOFをプログラムで検知できるようにすることですが、私は別の方法で解決できたので、それを以下で解説します。

pdfminerを使用

PDF内のテキストの読み取りにはPyPDF2ではなく、pdfminerモジュールを使用しました。

pdfminerモジュールはPDFからテキストを抽出するためによく使用されるモジュールです。
標準モジュールではないので、使用する場合はpipでインストールしておく必要があります。

pdfminerについて詳しい解説は以下記事をご参考ください。

事項で紹介するサンプルプログラムでは、pdfminerモジュールで読み取ったテキストをテキストファイルに張り付けています。

実行していただくとわかりますが、PyPDF2ではEOFエラーが出ていたPDFからテキストを抽出することができるようになっています。

プログラムのソース

PdfReadErrorが発生したPDFのテキストを抽出できるサンプルプログラムを以下にご紹介します。

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

def convert(path):
    rsrcmgr = PDFResourceManager()
    strio = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    laparams.detect_vertical = True
    text_c = TextConverter(rsrcmgr, strio, codec=codec, laparams=laparams)
    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, text_c)
    maxpages = 0
    caching = True
    pagenos=set()
    result = ''
    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages,caching=caching, check_extractable=True):
        interpreter.process_page(page)

        str_get = strio.getvalue()
        if str_get.isascii():
            result += str_get

    fp.close()
    text_c.close()
    strio.close()
    return result

txt = convert('pdf.pdf')

file = open('pdf.txt', 'w')
file.write(txt)
file.close()

まとめ

本記事「PdfReadError:EOF marker not foundの解決方法(PyPDF2)」はいかがでしたか。

PDFからテキスト抽出する際に私と同じようにエラーが発生した方も多いと思います。

ぜひ今回紹介したエラーの回避方法で、エラーを解決して開発を進めていただければと思います。