Поиск текста в PDF с помощью Python?

Проблема
Я пытаюсь определить, какой тип документа (например, мольба, переписка, повестка и т.д.), Просматривая его текст, предпочтительно используя python. Все PDF файлы доступны для поиска, но я не нашел решения для его синтаксического анализа с помощью python и применения script для его поиска (не до тех пор, пока оно не будет конвертировано в текстовый файл, но это может быть ресурсоемким для n документов).

Что я сделал до сих пор
Я просмотрел документацию pypdf, pdfminer, adobe pdf и любые вопросы, которые я мог найти (хотя, похоже, никто не решал эту проблему напрямую). PDFminer, кажется, имеет наибольший потенциал, но после прочтения документации я даже не уверен, с чего начать.

Есть ли простой, эффективный метод для чтения PDF-текста, будь то по странице, строке или всему документу? Или любые другие способы обхода?

Ответ 1

Это называется PDF-добычей, и это очень сложно, потому что:

  • PDF - это формат документа, предназначенный для печати, а не для анализа. Внутри документа PDF текст не имеет особого порядка (если заказ не является важным для печати), большую часть времени теряется исходная текстовая структура (буквы не могут быть сгруппированы, поскольку слова и слова не могут быть сгруппированы в предложениях, а порядок они помещаются в бумагу, часто бывает случайным).
  • Существует множество программ, создающих PDF файлы, многие из которых являются дефектными.

Инструменты, такие как PDFminer, используют эвристику для повторного группирования букв и слов в зависимости от их положения на странице. Я согласен, интерфейс довольно низкий, но имеет смысл, когда вы знаете, какую проблему они пытаются решить (в конце концов, важно выбрать, насколько близко от соседей должна быть буква/слово/строка, чтобы считаться частью абзаца).

Дорогая альтернатива (с точки зрения времени/мощности компьютера) создает изображения для каждой страницы и подает их на OCR, может быть стоит попробовать, если у вас есть очень хорошее OCR.

Поэтому мой ответ - нет, нет простого метода эффективного извлечения файлов из PDF файлов - если ваши документы имеют известную структуру, вы можете точно настроить правила и получить хорошие результаты, но это всегда азартная игра,

Я бы очень хотел, чтобы меня доказали неправильно.

[Обновить]

Ответ не изменился, но недавно я был вовлечен в два проекта: один из них использует компьютерное зрение, чтобы извлечь данные из отсканированных форм больницы. Другие извлечения данных из судебных записей. Я узнал:

  1. В 2018 году компьютерное зрение достигнет простых смертных. Если у вас есть хороший образец уже классифицированных документов, вы можете использовать OpenCV или SciKit-Image для извлечения функций и обучения классификатора машинного обучения, чтобы определить, какой тип документа.

  2. Если PDF, который вы анализируете, является "доступным для поиска", вы можете очень быстро извлечь весь текст, используя программное обеспечение, такое как pdftotext и байесовский фильтр (такой же алгоритм, который используется для классификации СПАМ).

Таким образом, нет надежного и эффективного метода для извлечения текста из файлов PDF, но вам может и не понадобиться его для решения проблемы (классификация типа документа).

Ответ 2

Я написал обширные системы для компании, в которой я работаю, чтобы конвертировать PDF в данные для обработки (счета-фактуры, расчеты, отсканированные билеты и т.д.), и @Paulo Scardine верна - нет абсолютно надежного и простого способа сделать это. Тем не менее, самый быстрый, самый надежный и наименее интенсивный способ - использовать pdftotext, часть набора инструментов xpdf. Этот инструмент быстро преобразует PDF с возможностью поиска в текстовый файл, который вы можете прочитать и проанализировать с помощью Python. Подсказка: используйте аргумент -layout. И, кстати, не все PDF доступны для поиска, только те, которые содержат текст. Некоторые PDF файлы содержат только изображения без текста.

Ответ 3

Я согласен с @Paulo PDF-добычей данных - огромная боль. Но у вас может быть успех с pdftotext, который является частью пакета Xpdf, доступного здесь:

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

Этого должно быть достаточно для вашей цели, если вы просто ищете одиночные ключевые слова.

pdftotext - утилита командной строки, но очень проста в использовании. Он предоставит вам текстовые файлы, с которыми вам будет легче работать.

Ответ 4

Недавно я начал использовать 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-документов. До сих пор я обнаружил, что это было точной, но болезненной.

Ответ 5

Я полностью зеленая рука, но как-то этот сценарий работает для меня:

# 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)

Ответ 6

Вот решение, которое мне показалось удобным для этой проблемы. В текстовой переменной вы получаете текст из PDF для поиска в нем. Но я сохранил также идею выплескивать текст по ключевым словам, как я нашел на этом веб-сайте: 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)