2013-06-13 17 views
8

Problem
Próbuję ustalić, jaki typ dokumentu jest (np. Prośba, korespondencja, wezwanie do stawiennictwa itp.), Przeszukując jego tekst, najlepiej za pomocą pythona. Wszystkie pliki PDF można przeszukiwać, ale nie znalazłem rozwiązania do analizowania go za pomocą pythona i zastosowania skryptu do przeszukiwania (najpierw nie trzeba go konwertować do pliku tekstowego, ale może to wymagać dużej ilości zasobów dla n dokumentów).Wyszukiwanie tekstu w pliku PDF za pomocą języka Python?

Co robiłem dotychczas
Przyjrzeliśmy się pypdf, pdfminer, Adobe PDF Documentation, a wszelkie pytania tutaj udało mi się znaleźć (choć żaden wydawało się bezpośrednio rozwiązać ten problem). PDFminer wydaje się mieć największy potencjał, ale po przeczytaniu dokumentacji nie jestem nawet pewien, od czego zacząć.

Czy istnieje prosta, skuteczna metoda czytania tekstu w formacie PDF, na stronie, linii lub w całym dokumencie? Lub inne obejścia?

+0

Szukałem tego samego rozwiązania. Problem polega na tym, że dokumenty PDF są znane z dzielenia tekstu na fragmenty trudne do złożenia. To zależy od programu, który napisał PDF. Skończyłem na używaniu PDFminera i dużo "elif" kodu do parsowania plików PDF. –

+1

Po prostu myśli, może nie praktyczne ... Jeśli jesteś zdesperowany, aby znaleźć obejście problemu, możesz spróbować wywołać pdfgrep (http://pdfgrep.sourceforge.net/), aby wykonać wyszukiwanie. –

Odpowiedz

17

To się nazywa PDF skrobanie i jest bardzo trudne, ponieważ:

  • PDF to format dokument przeznaczony do wydrukowania, aby nie być analizowany. Wewnątrz dokumentu PDF tekst nie ma określonej kolejności (chyba że zamówienie jest ważne dla drukowania), w większości przypadków oryginalna struktura tekstu jest tracona (litery nie mogą być zgrupowane , ponieważ słowa i słowa nie mogą być zgrupowane w zdaniach, i kolejność są umieszczane w papier jest często losowy).
  • Istnieje mnóstwo oprogramowania generującego pliki PDF, wiele z nich jest uszkodzonych.

Narzędzia takie jak PDFminer wykorzystują heurystykę do grupowania liter i słów w zależności od ich pozycji na stronie. Zgadzam się, interfejs jest dość niski, ale ma to więcej sensu, gdy wiesz, jaki problem próbują rozwiązać (w końcu, liczy się to, jak blisko sąsiadów musi być litera/słowo/linia aby zostać uznanym za część akapitu).

Droższą alternatywą (pod względem czasu/mocy komputera) jest generowanie obrazów dla każdej strony i podawanie ich do OCR, może warto spróbować, jeśli masz bardzo dobre OCR.

Więc moja odpowiedź brzmi: nie, nie ma czegoś takiego jak prosta, skuteczna metoda wydobywania tekstu z plików PDF - jeśli twoje dokumenty mają znaną strukturę, możesz dostroić reguły i uzyskać dobre wyniki, ale jest zawsze hazardem.

Naprawdę chciałbym zostać udowodniony źle.

+0

Wszystkie dokumenty zostały zeskanowane jako pliki PDF i rozpoznane przez OCR, aby można je było wyszukać - czy to coś innego niż opisywane? – Insarov

+0

@Insarov: Dokładnie o tym mówię, każde OCR warte swojej pensji będzie miało opcję wyprowadzenia czystego pliku tekstowego wraz z plikiem PDF. –

3

Zgadzam się z wydobywaniem danych @Paulo PDF to ogromny problem. Ale może masz sukces z pdftotext który jest częścią pakietu Xpdf swobodnie dostępnego tutaj:

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

ten powinien być wystarczający dla celów, jeśli tylko szukasz pojedynczych słów kluczowych.

pdftotext to narzędzie wiersza poleceń, ale bardzo proste w użyciu. Da ci pliki tekstowe, z którymi możesz łatwiej pracować.

6

Napisałem obszerne systemy dla firmy, w której pracuję, aby przekonwertować pliki PDF na dane do przetwarzania (faktury, rozliczenia, zeskanowane bilety itp.) i @Paulo Scardine jest poprawny - nie ma w pełni niezawodnego i łatwego sposobu na zrobienie tego. Powiedział, że najszybszym, najbardziej niezawodnym i najmniej intensywnym sposobem jest użycie pdftotext, części zestawu xpdf. To narzędzie szybko przekształci wyszukiwane pliki PDF w plik tekstowy, który można odczytać i przeanalizować za pomocą Pythona. Wskazówka: użyj argumentu -layout. A przy okazji, nie wszystkie pliki PDF można przeszukiwać, tylko te, które zawierają tekst. Niektóre pliki PDF zawierają tylko obrazy bez tekstu.

+0

dlaczego jest to najszybszy i najbardziej niezawodny sposób? Jakieś dowody? –

+1

Jeśli istnieje sposób przekonwertowania pliku PDF na plik tekstowy, czy istnieje sposób, aby to zrobić bez pisania nowego pliku? Coś jak czytanie dokumentu w pamięci? (Przynajmniej w sposób, który jest tak prosty jak konwersja?). – Insarov

+0

@Insarov, nie sądzę, nie z pdftotext. Ale mogę się mylić, musisz sprawdzić dokumenty. Możesz to zrobić przy pomocy pyPdf i pdfminer, ale są one dużo wolniejsze niż pdftotext, nawet przy zapisie pdftotext do pliku. – MikeHunter

2

Niedawno zacząłem używać ScraperWiki do robienia tego, co opisałeś.

Oto example używania ScraperWiki do wyodrębniania danych PDF.

Funkcja scraperwiki.pdftoxml() zwraca strukturę XML.

Następnie można użyć BeautifulSoup, aby przeanalizować go w drzewie nawigacyjnym.

Oto mój kod -

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 

Ten kod będzie drukować całość wielki brzydki stos <text> tagów. Każda strona jest oddzielona </page>, jeśli to pocieszenie.

Jeśli chcesz zawartość wewnątrz <text> znaczników, które mogą obejmować nagłówki zapakowane w <b> na przykład użyć line.contents

Jeśli chcesz tylko każdy wiersz tekstu, z wyłączeniem tagów, użyj line.getText()

To niechlujny i bolesny, ale to zadziała w przypadku dokumentów PDF z możliwością wyszukiwania. Do tej pory odkryłem, że jest to dokładne, ale bolesne.

+1

Próbowałem używać scraperwiki, otrzymuję System nie może znaleźć określonego błędu ścieżki. @JasTonAChair - każda doceniona pomoc. – user1211

+0

@JasTonAChair otrzymuję błąd: - BeautifulSoup ([Twój znaczniki]) do tego: BeautifulSoup ([Twoja markup] "lxml") – venkat

0

Oto rozwiązanie, które uważam za wygodne dla tego problemu. W zmiennej tekstowej otrzymujesz tekst z pliku PDF, aby go wyszukać. Ale ja zachowałem również ideę spiting tekst w słowach kluczowych, jak znalazłem na tej stronie: https://medium.com/@rqaiserr/how-to-convert-pdfs-into-searchable-key-words-with-python-85aab86c544f od gdybym wziął to rozwiązanie, choć czyni NLTK nie było bardzo proste, to może być przydatne dla innych celów:

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) 
Powiązane problemy