Как использовать pdfminer в качестве библиотеки
Я пытаюсь получить текстовые данные из PDF с помощью pdfminer. Я в состоянии извлечь данные .txt файл успешно с помощью инструмента командной строки pdfminer pdf2txt.py в настоящее время я делаю это, а затем использую скрипт python для очистки .txt-файл. Я хотел бы включить процесс извлечения pdf в скрипт и сохранить себе шаг.
Я думал, что я на что-то, когда я нашел эту ссылку, но у меня не было успеха ни с одним из решения. Возможно, функция, указанная там, должна быть обновлена снова, потому что я использую более новую версию pdfminer.
я также попробовал функцию, показанную здесь, но она также не работает.
другой подход, который я пробовал, состоял в том, чтобы вызвать скрипт в скрипте с помощью os.system
. Это тоже было неудачно.
Я использую Python версии 2.7.1 и pdfminer версии 20110227.
14 ответов:
вот очищенная версия, которую я, наконец, создал, которая работала для меня. Следующее просто возвращает строку в формате PDF, учитывая ее имя файла. Надеюсь, это сэкономит кому-то время.
from pdfminer.pdfinterp import PDFResourceManager, process_pdf from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from cStringIO import StringIO def convert_pdf(path): rsrcmgr = PDFResourceManager() retstr = StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) fp = file(path, 'rb') process_pdf(rsrcmgr, device, fp) fp.close() device.close() str = retstr.getvalue() retstr.close() return str
это решение действовало до изменения API в ноябре 2013 года.
вот новое решение, которое работает с последней версией:
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from cStringIO import StringIO def convert_pdf_to_txt(path): 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
Я знаю, что это плохой вкус, чтобы ответить на свой собственный вопрос, но я думаю, что я, возможно, понял это, и я не хочу, чтобы кто-то еще тратить свое время на поиски решения моей проблемы.
я последовал предложению в одной из ссылок, опубликованных в моем вопросе, и повторно назначил текущий pdf2txt.py скрипт входит в состав pdfminer. Вот функция в случае, если она полезна кому-либо еще. Спасибо пользователю skyl за публикацию этого ответа, все, что мне нужно было сделать, это сделать пару изменения, чтобы заставить его работать с текущей версией pdfminer.
эта функция принимает pdf и создает .txt файл в том же каталоге с тем же именем.
def convert_pdf(path, outtype='txt', opts={}): import sys from pdfminer.pdfparser import PDFDocument, PDFParser from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf from pdfminer.pdfdevice import PDFDevice, TagExtractor from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter from pdfminer.cmapdb import CMapDB from pdfminer.layout import LAParams import getopt outfile = path[:-3] + outtype outdir = '/'.join(path.split('/')[:-1]) # debug option debug = 0 # input option password = '' pagenos = set() maxpages = 0 # output option # ?outfile = None # ?outtype = None outdir = None #layoutmode = 'normal' codec = 'utf-8' pageno = 1 scale = 1 showpageno = True laparams = LAParams() for (k, v) in opts: if k == '-d': debug += 1 elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') ) elif k == '-m': maxpages = int(v) elif k == '-P': password = v elif k == '-o': outfile = v elif k == '-n': laparams = None elif k == '-A': laparams.all_texts = True elif k == '-V': laparams.detect_vertical = True elif k == '-M': laparams.char_margin = float(v) elif k == '-L': laparams.line_margin = float(v) elif k == '-W': laparams.word_margin = float(v) elif k == '-F': laparams.boxes_flow = float(v) elif k == '-Y': layoutmode = v elif k == '-O': outdir = v elif k == '-t': outtype = v elif k == '-c': codec = v elif k == '-s': scale = float(v) # #PDFDocument.debug = debug #PDFParser.debug = debug CMapDB.debug = debug PDFResourceManager.debug = debug PDFPageInterpreter.debug = debug PDFDevice.debug = debug # rsrcmgr = PDFResourceManager() outtype = 'text' if outfile: outfp = file(outfile, 'w') else: outfp = sys.stdout device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams) fp = file(path, 'rb') process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password, check_extractable=True) fp.close() device.close() outfp.close() return
это сработало для меня, используя самую последнюю версию pdfminer (по состоянию на сентябрь 2014 года):
from pdfminer.pdfparser import PDFParser from pdfminer.pdfdocument import PDFDocument from pdfminer.pdfpage import PDFPage from pdfminer.pdfpage import PDFTextExtractionNotAllowed from pdfminer.pdfinterp import PDFResourceManager from pdfminer.pdfinterp import PDFPageInterpreter from pdfminer.pdfdevice import PDFDevice from pdfminer.converter import TextConverter from pdfminer.layout import LAParams import unicodedata, codecs from cStringIO import StringIO def getPDFText(pdfFilenamePath): retstr = StringIO() parser = PDFParser(open(pdfFilenamePath,'r')) try: document = PDFDocument(parser) except Exception as e: print(pdfFilenamePath,'is not a readable pdf') return '' if document.is_extractable: rsrcmgr = PDFResourceManager() device = TextConverter(rsrcmgr,retstr, codec='ascii' , laparams = LAParams()) interpreter = PDFPageInterpreter(rsrcmgr, device) for page in PDFPage.create_pages(document): interpreter.process_page(page) return retstr.getvalue() else: print(pdfFilenamePath,"Warning: could not extract text from pdf file.") return '' if __name__ == '__main__': words = getPDFText(path)
вот мое решение
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from io import StringIO import os def convert_pdf_to_txt(path, pages=None): if not pages: pagenums = set() else: pagenums = set(pages) output = StringIO() manager = PDFResourceManager() converter = TextConverter(manager, output, laparams=LAParams()) interpreter = PDFPageInterpreter(manager, converter) infile = open(path, 'rb') for page in PDFPage.get_pages(infile, pagenums): interpreter.process_page(page) infile.close() converter.close() text = output.getvalue() output.close() return text
например, вы просто хотите прочитать первые 3 страницы pdf-файла:
text = convert('../Data/EN-FINAL Table 9.pdf', pages=[0,1,2])
pdfminer.шесть==20160614
python: 3.x
если вы работаете с очищенными данными через urllib2, попробуйте это (который разработан и объяснен здесь):
def pdf_to_text(scraped_pdf_data): from pdfminer.pdfinterp import PDFResourceManager, process_pdf from pdfminer.pdfdevice import PDFDevice from pdfminer.converter import TextConverter from pdfminer.layout import LAParams import StringIO fp = StringIO.StringIO() fp.write(scraped_pdf_data) fp.seek(0) outfp = StringIO.StringIO() rsrcmgr = PDFResourceManager() device = TextConverter(rsrcmgr, outfp, laparams=LAParams()) process_pdf(rsrcmgr, device, fp) device.close() t = outfp.getvalue() outfp.close() fp.close() return t
как и другие ответы, код здесь адаптирует утилиту pdf2txt, которую предоставляет сам PDFMiner. Таким образом, вы также можете конвертировать в html или xml-просто sub
HTMLConverter
илиXMLConverter
наTextConverter
везде выше.
следующая модификация ответов non-process_pdf извлекает текст прямо из имени строки URL и работает с версией 20140328 и Python 2.7:
from urllib2 import urlopen from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from cStringIO import StringIO def convert_pdf_to_txt(url): rsrcmgr = PDFResourceManager() retstr = StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) scrape = urlopen(url).read() fp = StringIO(scrape) 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() textstr = retstr.getvalue() retstr.close() return textstr
следующий код работает для меня с последней версией PDFMiner он принимает путь pdf и возвращает текст .формат txt.
P. S: это модификация ответа выше.
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from cStringIO import StringIO def convert_pdf_to_txt(path, outtype='txt'): outfile = path[:-3] + outtype rsrcmgr = PDFResourceManager() codec = 'utf-8' laparams = LAParams() if outfile: outfp = file(outfile, 'w') else: outfp = sys.stdout device = TextConverter(rsrcmgr, outfp, 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() outfp.close() return
вот очищенная версия, которую я, наконец, создал, которая работала для меня. Следующее просто возвращает строку в формате PDF, учитывая ее имя файла. Надеюсь, это сэкономит кому-то время.
from pdfminer.pdfinterp import PDFResourceManager, process_pdf from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from cStringIO import StringIO def convert_pdf(path): rsrcmgr = PDFResourceManager() retstr = StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) fp = file(path, 'rb') process_pdf(rsrcmgr, device, fp) fp.close() device.close() str = retstr.getvalue() retstr.close() return str
может ли кто-нибудь сказать мне : есть ли какое-то конкретное место, где должен быть размещен файл pdf??
на всякий случай, если кто-то еще нуждается в этом, получил его работа с запросами и python 3.4. спасибо @bahmait за его ответ выше :)
import requests from io import StringIO from pdfminer.pdfinterp import PDFResourceManager, process_pdf from pdfminer.converter import TextConverter from pdfminer.layout import LAParams def pdf_to_text(url=None): text = None pdf = requests.get(url) if pdf.ok: fp = StringIO(str(pdf.content, 'utf-8')) outfp = StringIO() rsrcmgr = PDFResourceManager() device = TextConverter(rsrcmgr, outfp, laparams=LAParams()) process_pdf(rsrcmgr, device, fp) device.close() text = outfp.getvalue() outfp.close() fp.close() return text if __name__ == "__main__": hello_world_text = pdf_to_text("https://bytebucket.org/hsoft/pdfminer3k/raw/28edfc91caed830674ca0b928f42571f7dee6091/samples/simple1.pdf") no_pdf = pdf_to_text('http://www.google.com/404') print(hello_world_text) print(no_pdf)
вот ответ, который работает с
pdfminer.six
запуск python 3.6. Он используетpdfminer.high_level
модуль, который абстрагирует много базовых деталей, если вы просто хотите получить необработанный текст из простого PDF-файла.import pdfminer import io def extract_raw_text(pdf_filename): output = io.StringIO() laparams = pdfminer.layout.LAParams() # Using the defaults seems to work fine with open(pdf_filename, "rb") as pdffile: pdfminer.high_level.extract_text_to_fp(pdffile, output, laparams=laparams) return output.getvalue()
спасибо user3577380
Я получаю pdfminer.шесть https://github.com/goulu/pdfminer
Я немного изменил для python3. 5, чтобы успешно разобрать локальный китайский PDF, но как я могу разобрать онлайн PDF с запросами? Например: http://pythonscraping.com/pages/warandpeace/chapter1.pdf
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from pdfminer.pdfparser import PDFParser from pdfminer.pdfdocument import PDFDocument from io import StringIO import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') def convert_pdf_to_txt(path): rsrcmgr = PDFResourceManager() retstr = StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) fp = open(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) text = retstr.getvalue() fp.close() device.close() retstr.close() print(text.encode('gb18030', 'ignore').decode('gb18030', 'ignore')) return text path_of_the_pdf_file = r'E:\迅雷下载\过表达Smad7基因对瘢痕疙瘩成纤维细胞的影响.pdf' convert_pdf_to_txt(path_of_the_pdf_file)
только если кому-то это все еще нужно: как распечатать HTML из PDF с помощью PDFMiner:
import sys import getopt from Core.Interfaces.IReader import IReader from pdfminer.pdfparser import PDFDocument, PDFParser from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf from pdfminer.pdfdevice import PDFDevice, TagExtractor from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter from pdfminer.cmapdb import CMapDB from pdfminer.layout import LAParams from cStringIO import StringIO class PdfReader(object): def __init__(self): pass def readText(self,path, outtype='text', opts={}): outfile = path[:-3] + outtype outdir = '/'.join(path.split('/')[:-1]) # debug option debug = 0 # input option password = '' pagenos = set() maxpages = 0 # output option # ?outfile = None # ?outtype = None outdir = None #layoutmode = 'normal' codec = 'utf-8' pageno = 1 scale = 1 showpageno = True laparams = LAParams() for (k, v) in opts: if k == '-d': debug += 1 elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') ) elif k == '-m': maxpages = int(v) elif k == '-P': password = v elif k == '-o': outfile = v elif k == '-n': laparams = None elif k == '-A': laparams.all_texts = True elif k == '-V': laparams.detect_vertical = True elif k == '-M': laparams.char_margin = float(v) elif k == '-L': laparams.line_margin = float(v) elif k == '-W': laparams.word_margin = float(v) elif k == '-F': laparams.boxes_flow = float(v) elif k == '-Y': layoutmode = v elif k == '-O': outdir = v elif k == '-t': outtype = v elif k == '-c': codec = v elif k == '-s': scale = float(v) print laparams # #PDFDocument.debug = debug #PDFParser.debug = debug CMapDB.debug = debug PDFResourceManager.debug = debug PDFPageInterpreter.debug = debug PDFDevice.debug = debug # rsrcmgr = PDFResourceManager() #outtype = 'text' outfp = StringIO() device = HTMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams) fp = file(path, 'rb') process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password, check_extractable=True) fp.close() device.close() print outfp.getvalue() outfp.close() return reader = PdfReader() opt = map(None,['-W','-L','-t'],[0.5,0.4,'html']) reader.readText("/test_data/test.pdf","html",opt)
следующие фрагменты кода могут извлекать простой текст из pdf-документов, используя последнюю версию pdfminer (по состоянию на 23-Mar-2016). Надеюсь, это поможет.
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from cStringIO import StringIO def convert_pdf_to_txt(path): rsrcmgr = PDFResourceManager() retstr = StringIO() codec = 'utf-8' laparams = LAParams() device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) fp = file(path, 'rb') parser = PDFParser(fp) doc = PDFDocument(parser) parser.set_document(doc) 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) text = retstr.getvalue() fp.close() device.close() retstr.close() print text return text convert_pdf_to_txt(<path_of_the_pdf_file>)