web-dev-qa-db-ja.com

PDFファイルのディレクトリからOCRを使用して効率的にテキストを抽出するにはどうすればよいですか?

PDFファイル(画像)の大きなディレクトリがありますが、ディレクトリ内のすべてのファイルからテキストを効率的に抽出するにはどうすればよいですか?。これまでのところ、次のことを試みました。

_import multiprocessing
import textract

def extract_txt(file_path):
    text = textract.process(file_path, method='tesseract')

p = multiprocessing.Pool(2)
file_path = ['/Users/user/Desktop/sample.pdf']
list(p.map(extract_txt, file_path))
_

しかし、それは機能していません...それは多くの時間がかかります(私は600ページのいくつかの文書を持っています)。さらに:a)ディレクトリ変換部分を効率的に処理する方法がわかりません。 b)ページ区切り文字を追加したいのですが、たとえば_<start/age = 1> ... page content ... <end/page = 1>_としましょう。しかし、これを行う方法がわかりません。

したがって、_extract_txt_で終わるディレクトリのすべての要素に_.pdf_関数を適用し、同じファイルを別のディレクトリに_.txt_形式で返し、ページを追加するにはどうすればよいですか。 OCRテキスト抽出付きのセパレータ?.

また、私はこのタスクを行うためにグーグルドキュメントを使用することに興味がありました、前述のテキスト抽出の問題を解決するためにプログラムでグーグルドキュメントを使用することは可能ですか?.

[〜#〜] update [〜#〜]

Roland Smithの回答を読んだ後の「ページ区切り文字の追加」の問題(_<start/age = 1> ... page content ... <end/page = 1>_)について、私は次のことを試みました。

_from PyPDF2 import PdfFileWriter, PdfFileReader
import textract


def extract_text(pdf_file):
    inputpdf = PdfFileReader(open(pdf_file, "rb"))
    for i in range(inputpdf.numPages):
        w = PdfFileWriter()
        w.addPage(inputpdf.getPage(i))
        outfname = 'page{:03d}.pdf'.format(i)
        with open(outfname, 'wb') as outfile:  # I presume you need `wb`.
             w.write(outfile)
        print('\n<begin page pos =' , i, '>\n')
        text = textract.process(str(outfname), method='tesseract')
        os.remove(outfname)  # clean up.
        print(str(text, 'utf8'))
        print('\n<end page pos =' , i, '>\n')

extract_text('/Users/user/Downloads/ImageOnly.pdf')
_

ただし、print()の部分にはまだ問題があります。印刷する代わりに、すべての出力をファイルに保存する方が便利だからです。したがって、出力をファイルにリダイレクトしようとしました。

_sys.stdout=open("test.txt","w")
print('\n<begin page pos =' , i, '>\n')
sys.stdout.close()
text = textract.process(str(outfname), method='tesseract')
os.remove(outfname)  # clean up.
sys.stdout=open("test.txt","w")
print(str(text, 'utf8'))
sys.stdout.close()
sys.stdout=open("test.txt","w")
print('\n<end page pos =' , i, '>\n')
sys.stdout.close()
_

ページ抽出/セパレーターのトリックを作成し、すべてをファイルに保存する方法についてのアイデアはありますか?...

16
john doe

あなたのコードでは、テキストを抽出していますが、それでは何もしません

次のようなものを試してください。

def extract_txt(file_path):
    text = textract.process(file_path, method='tesseract')
    outfn = file_path[:-4] + '.txt'  # assuming filenames end with '.pdf'
    with open(outfn, 'wb') as output_file:
        output_file.write(text)
    return file_path

これにより、同じ名前で拡張子が.txtのファイルにテキストが書き込まれます。

また、元のファイルのパスを返し、このファイルが完了したことを親に知らせます。

したがって、マッピングコードを次のように変更します。

p = multiprocessing.Pool()
file_path = ['/Users/user/Desktop/sample.pdf']
for fn in p.imap_unordered(extract_txt, file_path):
    print('completed file:', fn)
  • Poolを作成するときに、引数を指定する必要はありません。デフォルトでは、CPUコアと同じ数のワーカーが作成されます。
  • imap_unorderedを使用すると、値が使用可能になるとすぐに値の生成を開始するイテレータが作成されます。
  • ワーカー関数がファイル名を返したので、それを印刷して、このファイルが完了したことをユーザーに知らせることができます。

編集1

追加の質問は、ページの境界をマークすることが可能かどうかです。私はそう思う。

確実に機能する方法は、PDFファイルをページに分割することです beforeOCR。poppler-utilsパッケージのpdfinfoを使用して、ドキュメントのページ数を確認できます。次に、pdfseparate同じpoppler-utilsパッケージから、Nページの1つのpdfファイルを1ページのNpdfファイルに変換します。次に単一ページをOCRすることができますPDFファイル。これにより、各ページのテキストは個別に。

または、ドキュメント全体をOCRしてから、改ページを検索することもできます。これは、ドキュメントのすべてのページに一定または予測可能なヘッダーまたはフッターがある場合にのみ機能します。おそらく、上記の方法ほど信頼性は高くありません。


編集2:

ファイルが必要な場合は、writeファイル:

from PyPDF2 import PdfFileWriter, PdfFileReader
import textract

def extract_text(pdf_file):
    inputpdf = PdfFileReader(open(pdf_file, "rb"))
    outfname = pdf_file[:-4] + '.txt' # Assuming PDF file name ends with ".pdf"
    with open(outfname, 'w') as textfile:
        for i in range(inputpdf.numPages):
            w = PdfFileWriter()
            w.addPage(inputpdf.getPage(i))
            outfname = 'page{:03d}.pdf'.format(i)
            with open(outfname, 'wb') as outfile:  # I presume you need `wb`.
                w.write(outfile)
            print('page', i)
            text = textract.process(outfname, method='tesseract')
            # Add header and footer.
            text = '\n<begin page pos = {}>\n'.format(i) + text + '\n<end page pos = {}>\n'.format(i)
            # Write the OCR-ed text to the output file.
            textfile.write(text)
            os.remove(outfname)  # clean up.
            print(text)
11
Roland Smith