web-dev-qa-db-ja.com

Pythonを使用してPDFでテキストを検索しますか?

問題
私は、できればpythonを使用して、テキストを検索することにより、ドキュメントの種類(たとえば、嘆願、通信、召喚状など)を判断しようとしています。すべてのPDFは検索可能ですが、pythonを使用して解析し、スクリプトを適用して検索するソリューションは見つかりませんでした(最初にテキストファイルに変換するのではなく、リソースである可能性があります) -nドキュメントに対して集中的)。

これまでにやったこと
pypdf、pdfminer、Adobe pdfのドキュメント、およびここで見つけられる質問を調べました(この問題を直接解決できるものはありませんでした)。 PDFminerは最も可能性が高いように見えますが、ドキュメントを読んだ後、どこから始めればよいかさえわかりません。

PDFテキストをページごと、行ごと、またはドキュメント全体で読むためのシンプルで効果的な方法はありますか?

25
Insarov

これはPDFマイニングと呼ばれ、次の理由で非常に困難です:

  • PDFは、解析されるのではなく、印刷されるように設計されたドキュメント形式です。 PDF文書内では、テキストは特定の順序ではなく(印刷に順序が重要でない限り)、ほとんどの場合、元のテキスト構造は失われます(文字は単語や単語としてグループ化されない場合があります文にグループ化されることはなく、それらが論文に記載される順序はしばしばランダムです。
  • PDFを生成するソフトウェアが大量にあり、その多くに欠陥があります。

PDFminerなどのツールは、ヒューリスティックを使用して、ページ内の位置に基づいて文字と単語を再びグループ化します。インターフェースはかなり低レベルですが、解決しようとしている問題を知っているとより理にかなっています(最終的には、隣人から手紙/単語/行がどれだけ近くにあるかを選択することが重要です段落の一部と見なされます)。

(時間/コンピューターの処理能力の点で)高価な代替手段は、各ページの画像を生成してOCRに供給することです。非常に優れたOCRがある場合は、試してみる価値があります。

だから私の答えはノーです、PDFファイルからテキストを抽出するためのシンプルで効果的な方法はありません-文書が既知の構造を持っている場合、ルールを微調整して取得することができます良い結果ですが、常にギャンブルです。

私は本当に間違ったことを証明したいと思います。

[更新]

答えは変わっていませんが、最近2つのプロジェクトに関与しました。1つはスキャンされた病院フォームからデータを抽出するためにコンピュータービジョンを使用しています。もう1つは、裁判所の記録からデータを抽出します。私が学んだことは:

  1. コンピュータービジョンは2018年には単なる人間の手の届くところにあります。既に分類されたドキュメントの良いサンプルがある場合は、OpenCVまたはSciKit-Imageを使用して特徴を抽出し、機械学習分類子をトレーニングしてドキュメントの種類を判断できます。

  2. 分析しているPDFが「検索可能」である場合、 pdftotext などのソフトウェアとベイジアンフィルター(同じ種類のアルゴリズム)を使用して、すべてのテキストを非常に遠くまで抽出できます。スパムの分類に使用されます)。

そのため、PDFファイルからテキストを抽出するための信頼できる効果的な方法はありませんが、手元の問題を解決するためにドキュメントの種類を分類する必要はありません。

32
Paulo Scardine

PDFを処理用のデータ(請求書、決済、スキャンされたチケットなど)に変換するために働いている会社のために広範なシステムを作成しました。@ Paulo Scardineは正しいです。 。とはいえ、最速で、最も信頼性が高く、最も負荷の少ない方法は、ツールの xpdf セットの一部であるpdftotextを使用することです。このツールは、検索可能なPDFをテキストファイルにすばやく変換し、Pythonで読み取りおよび解析できます。ヒント:-layout引数を使用します。ところで、すべてのPDFが検索可能というわけではなく、テキストを含むPDFのみが検索可能です。一部のPDFには、テキストのない画像のみが含まれています。

12
MikeHunter

私は完全に緑の手ですが、どういうわけかこのスクリプトは私のために機能します:

# import packages
import PyPDF2
import re

# open the pdf file
object = PyPDF2.PdfFileReader("test.pdf")

# get number of pages
NumPages = object.getNumPages()

# define keyterms
String = "Social"

# extract text and do the search
for i in range(0, NumPages):
    PageObj = object.getPage(i)
    print("this is page " + str(i)) 
    Text = PageObj.extractText() 
    # print(Text)
    ResSearch = re.search(String, Text)
    print(ResSearch)
11
Emma Yu

私は最近、あなたが説明したことをするためにScraperWikiを使い始めました。

ScraperWikiを使用してPDFデータを抽出します。

scraperwiki.pdftoxml()関数は、XML構造を返します。

その後、BeautifulSoupを使用して、それを解析してナビゲーション可能なツリーにすることができます。

ここに私のコードがあります-

_import scraperwiki, urllib2
from bs4 import BeautifulSoup

def send_Request(url):
#Get content, regardless of whether an HTML, XML or PDF file
    pageContent = urllib2.urlopen(url)
    return pageContent

def process_PDF(fileLocation):
#Use this to get PDF, covert to XML
    pdfToProcess = send_Request(fileLocation)
    pdfToObject = scraperwiki.pdftoxml(pdfToProcess.read())
    return pdfToObject

def parse_HTML_tree(contentToParse):
#returns a navigatibale tree, which you can iterate through
    soup = BeautifulSoup(contentToParse)
    return soup

pdf = process_PDF('http://greenteapress.com/thinkstats/thinkstats.pdf')
pdfToSoup = parse_HTML_tree(pdf)
soupToArray = pdfToSoup.findAll('text')
for line in soupToArray:
    print line
_

このコードは、_<text>_タグの大きくてい山全体を出力します。慰めの場合、各ページは_</page>_で区切られます。

たとえば_<text>_でラップされた見出しを含む可能性のある_<b>_タグ内のコンテンツが必要な場合は、_line.contents_を使用します

タグを含めずにテキストの各行のみが必要な場合は、line.getText()を使用します

面倒で痛みを伴いますが、これは検索可能なPDF docs。

6
JasTonAChair

@Paulo PDFデータマイニングは大きな痛みです。しかし、ここで無料で利用できるXpdfスイートの一部であるpdftotextで成功するかもしれません。

http://www.foolabs.com/xpdf/download.html

単一のキーワードを探している場合は、これで目的に十分です。

pdftotextはコマンドラインユーティリティですが、使用するのは非常に簡単です。これにより、作業しやすいテキストファイルが得られます。

4
qwwqwwq

この問題に対して私が快適だと思った解決策を以下に示します。テキスト変数では、PDFから検索するためにテキストを取得します。しかし、このWebサイトで見つけたように、キーワードでテキストをスパイするという考えも保持しています: https://medium.com/@rqaiserr/how-to-convert-pdfs-into-searchable-key-words-with-python-85aab86c544f nltkの作成はそれほど簡単ではありませんでしたが、次の目的に役立つ場合があります。

import PyPDF2 
import textract

from nltk.tokenize import Word_tokenize
from nltk.corpus import stopwords

def searchInPDF(filename, key):
    occurrences = 0
    pdfFileObj = open(filename,'rb')
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
    num_pages = pdfReader.numPages
    count = 0
    text = ""
    while count < num_pages:
        pageObj = pdfReader.getPage(count)
        count +=1
        text += pageObj.extractText()
    if text != "":
       text = text
    else:
       text = textract.process(filename, method='tesseract', language='eng')
    tokens = Word_tokenize(text)
    punctuation = ['(',')',';',':','[',']',',']
    stop_words = stopwords.words('english')
    keywords = [Word for Word in tokens if not Word in stop_words and  not Word in punctuation]
    for k in keywords:
        if key == k: occurrences+=1
    return occurrences 

pdf_filename = '/home/florin/Downloads/python.pdf'
search_for = 'string'
print searchInPDF (pdf_filename,search_for)
2
florin27