PDFMiner - перебирая страницы и переводя их в текст
Поэтому я пытаюсь получить определенный фрагмент текста из некоторых PDF-файлов, и я использую Python с PDFMiner, но у меня возникли некоторые проблемы из-за изменений в API, произошедших в ноябре 2013 года. По сути, чтобы получить часть текста, которую я хочу, из PDF, мне в настоящее время нужно преобразовать весь файл в текст, а затем использовать строковые функции, чтобы получить нужную часть. Что я хочу сделать, так это перебрать каждую страницу PDF и конвертировать каждую в текст, одну за другой. Затем, как только я найду нужную часть, я просто перестану читать этот PDF.
Я опубликую код, который находится в моем текстовом редакторе atm, но это не рабочая версия, а скорее версия для решения проблемы: P
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfdevice import PDFDevice
from pdfminer.converter import LTChar, TextConverter
from pdfminer.layout import LAParams
from subprocess import call
from cStringIO import StringIO
import re
import sys
import os
argNum = len(sys.argv)
pdfLoc = str(sys.argv[1]) #CLI arguments
def convert_pdf_to_txt(path): #converts pdf to raw text (not my function)
rsrcmgr = PDFResourceManager()
retstr = StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
fp = file(path, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos=set()
for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)
fp.close()
device.close()
str = retstr.getvalue()
retstr.close()
return str
if (pdfLoc[-4:] == ".pdf"):
contents = ""
try: # Get the outlines (contents) of the document
fp = open(pdfLoc, 'rb') #open a pdf document for reading
parser = PDFParser(fp)
document = PDFDocument(parser)
outlines = document.get_outlines()
for (level,title,dest,a,se) in outlines:
title = re.sub(r".*\s", "", title) #get raw titles, stripped of formatting
contents += title + "\n"
except: #if pdfMiner can't get contents then manually get contents from text conversion
#contents = convert_pdf_to_txt(pdfLoc)
#startToCpos = contents.find("TABLE OF CONTENTS")
#endToCpos = contents.rfind(". . .")
#contents = contents[startToCpos:endToCpos+8]
fp = open(pdfLoc, 'rb') #open a pdf document for reading
parser = PDFParser(fp)
document = PDFDocument(parser)
pages = PDFPage(document, 3, {'Resources':'thing', 'MediaBox':'Thing'}) #God knows what's going on here
for pageNumber, page in enumerate(pages.get_pages(PDFDocument, fp)): #The hell is the first argument?
if pageNumber == 42:
print "Hello"
#for line in s:
# print line
# if (re.search("(\.\s){2,}", line) and not re.search("NOTES|SCOPE", line)):
# line = re.sub("(\.\s){2,}", "", line)
# line = re.sub("(\s?)*[0-9]*\n", "\n", line)
# line = re.sub("^\s", "", line)
# print line,
#contents = contents.lower()
#contents = re.sub("“", "\"", contents)
#contents = re.sub("”", "\"", contents)
#contents = re.sub("fi", "f", contents)
#contents = re.sub(r"(TABLE OF CONTENTS|LIST OF TABLES|SCOPE|REFERENCED DOCUMENTS|Identification|System (o|O)verview|Document (o|O)verview|Title|Page|Table|Tab)(\n)?|\.\s?|Section|[0-9]", "", contents)
#contents = re.sub(r"This document contains proprietary information and may not be reproduced in any form whatsoever, nor may be used by or its contents divulged to third\nparties without written permission from the ownerAll rights reservedNumber: STP SMEDate: -Jul-Issue: A of CMC STPNHIndustriesCLASSIFICATION\nNATO UNCLASSIFIED AGUSTAEUROCOPTEREUROCOPTER DEUTSCHLAND FOKKER", "", contents)
#contents = re.sub(r"(\r?\n){2,}", "", contents)
#contents = contents.lstrip()
#contents = contents.rstrip()
#print contents
else:
print "Not a valid PDF file"
Это старый способ сделать это (или, по крайней мере, идея о том, как это делалось по-старому, тема мне не очень пригодилась). Но теперь я должен использовать PDFPage.get_pages вместо PDFDocument.get_pages, а методы и их аргументы совершенно разные.
В настоящее время я пытаюсь выяснить, что же такое переменная 'Klass', которую я передаю методу get_pages в PDFPage.
Если бы кто-нибудь мог пролить свет на эту часть API или даже привести рабочий пример, я был бы очень признателен.
2 ответа
Попробуйте использовать PyPDF2. Это намного проще в использовании и не так излишне многофункционально, как PDFMiner (что хорошо в вашем случае). Вот то, что вы хотели, и это очень просто реализовать.
from PyPDF2 import PdfFileReader
PDF = PdfFileReader(file(pdf_fp, 'rb'))
if PDF.isEncrypted:
decrypt = PDF.decrypt('')
if decrypt == 0:
print "Password Protected PDF: " + pdf_fp
raise Exception("Nope")
elif decrypt == 1 or decrypt == 2:
print "Successfully Decrypted PDF"
for page in PDF.pages:
print page.extractText()
'''page.extractText() is the unicode string of the contents of the page
And I am assuming you know how to play with a string and use regex
If you find what you want just break like so:
if some_condition == True:
break'''
Может быть, я немного опоздал, и вы уже решили это, но все же, для дальнейшего использования:
После долгих поисков я вспомнил эту ссылку, из которой я бы указал следующую часть (соответствующие части выделены жирным шрифтом):
Python решил сделать методы таким образом, чтобы экземпляр, которому принадлежит метод, передавался автоматически, но не получался автоматически: первый параметр методов - это экземпляр, к которому вызывается метод. Это делает методы полностью такими же, как функции, и оставляет фактическое имя для использования на ваше усмотрение (хотя self является соглашением, и люди обычно недовольны вами, когда вы используете что-то еще.) Self не является особенным для кода, оно просто другой объект.