¿Cómo puedo usar pdfminer como una biblioteca

Estoy tratando de conseguir los datos de texto de un pdf con pdfminer. Soy capaz de extraer estos datos a una .archivo txt con éxito con la pdfminer herramienta de línea de comandos pdf2txt.py. Yo actualmente hago esto y, a continuación, utilizar una secuencia de comandos de python para limpiar el .archivo txt. Me gustaría incorporar el pdf extracto de proceso en la secuencia de comandos y salvar a mí mismo un paso.

Pensé que era algo cuando he encontrado este enlace, pero no tuve éxito con alguna de las soluciones. Tal vez la función indicada no necesita ser actualizado de nuevo porque estoy utilizando una versión más reciente de pdfminer.

También probé la función que se muestra aquí, pero también no funciona.

Otro enfoque que probé fue a llamar a la secuencia de comandos dentro de una secuencia de comandos mediante os.system. Esto también fue infructuoso.

Estoy usando la versión de Python 2.7.1 y pdfminer versión 20110227.

  • Has probado a este?
  • Me hizo mirar por encima de la api de gracias, pero por desgracia mi python habilidades no son lo suficientemente fuertes para conseguir un trabajo de la función.
InformationsquelleAutor jmeich | 2011-04-20

14 Kommentare

  1. 69

    Aquí es un limpiado la versión que finalmente produjo la que trabajó para mí. El siguiente simplemente devuelve la cadena de caracteres en un archivo PDF, dado que su nombre de archivo. Espero que esto ahorra tiempo alguien.

    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

    Esta solución es válida hasta Cambios en el API en noviembre de 2013.

    • Gracias por el esfuerzo !
    • Sólo para tu INFORMACIÓN, este ya no funciona en la versión actual de pdfminer – me sale «ImportError: no se puede importar el nombre process_pdf»
    • aquí es una solución de trabajo: stackoverflow.com/questions/26494211/… (a partir de mediados de noviembre ’15)
    • process_pdf era simplemente reemplazado por PDFPageInterpreter
  2. 76

    Aquí es una nueva solución que funciona con la última versión:

    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
    • genial!!! por último, un ejecutando una solución sin usar process_pdf 🙂 he intentado con el simple1.pdf de la oficial repositorio git
    • Este es el trabajo para la versión pdfminer 20131113. Gracias.
    • ¿Cómo se utiliza este con el construido en opciones? Es allí una manera de especificar que el número de página para convertir?
    • si desea obtener una salida html acaba de agregar HTMLConverter a las importaciones y en la función, en lugar de TextConverter poner HTMLConverter. Simple como eso.
    • La roca el hombre también está trabajando con pdfminer última versión(20140328): importación pdfminer de impresión pdfminer.__versión__ 20140328
    • Grande con un menor edit: NO usar str como un nombre de variable. str es una función de python.
    • Puedo obtener ImportError: No module named pdfpage

  3. 12

    Sé que es de mal gusto para responder a su propia pregunta, pero creo que puede tener di cuenta de esto y yo no quiero que nadie más que perder su tiempo buscando una solución a mi problema.

    He seguido la sugerencia en uno de los enlaces publicados en mi pregunta y re-propuso el actual pdf2txt.py script incluido con pdfminer. Esta es la función en caso de que sea útil a alguien más. Gracias a que el usuario skyl para la publicación de la respuesta, todo lo que tenía que era hacer un par de cambios para que funcione con la versión actual de pdfminer.

    Esta función toma un pdf y crea una .txt archivo en el mismo directorio con el mismo nombre.

    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
    • está bien para responder a sus propias preguntas, no te preocupes.
    • Yo también reutilizar ese código. Simplemente podría ser un poco más delgado
    • Es muy deseable para responder a su propia pregunta, debido a la razón que usted menciona
  4. 12

    Esto funcionó para mí usando la versión más reciente de pdfminer (a partir de septiembre de 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 io 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)
  5. 6

    Aquí está mi solución

    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

    Por ejemplo solo quieres leer las primeras 3 páginas de un archivo pdf:

    text = convert('../Data/EN-FINAL Table 9.pdf', pages=[0,1,2])

    pdfminer.seis==20160614

    python: 3.x

    • Bueno! Esto funcionó para mí. Python 3.6.2 pdfminer.seis
    • La mejor solución en Python 3.6 / pdfminer.seis / Windows 7
  6. 4

    La siguiente modificación de la no-process_pdf respuestas extrae el texto directamente desde una URL del nombre de la cadena y funciona con la versión 20140328 y 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
  7. 3

    Si usted está trabajando con raspado de datos a través de urllib2, intenta esto (que es desarrollado y explicado aquí):

    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

    Como las otras respuestas, el código aquí adapta el pdf2txt utilidad que PDFMiner en sí misma ofrece. Usted puede también convertir a html o xml — sub HTMLConverter o XMLConverter para TextConverter en todas partes de arriba.

  8. 3

    El siguiente código me funciona con la última versión de PDFMiner lleva camino de pdf y devolver el texto en .formato txt.

    P. S: Ésta es una modificación de la respuesta anterior.

    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
  9. 3

    sólo en caso de que alguien todavía necesita esta,
    consiguió trabajo con las solicitudes y python 3.4.
    gracias a @bahmait por su respuesta anterior 🙂

    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)
    • Tienes pdfminer de trabajo con python3? Puedes compartir cómo?
    • ¿le ha dado a este hombre una oportunidad? [link]pypi.python.org/pypi/pdfminer3k … doesnt como su muy apoyado más, pero me dio un buen salto fuera de punto. al final, he utilizado sus pdf2txt módulo mixto de algunos de los métodos de pypdf2 para mi caso de uso específico.
  10. 3

    He aquí una respuesta que trabaja con pdfminer.six ejecutando python 3.6. Utiliza el pdfminer.high_level módulo de resúmenes de distancia mucho de la subyacente detalle si lo que desea es obtener el texto en bruto a partir de un simple archivo 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()
  11. 2

    Aquí es un limpiado la versión que finalmente produjo la que trabajó para mí. El siguiente simplemente devuelve la cadena de caracteres en un archivo PDF, dado que su nombre de archivo. Espero que esto ahorra tiempo alguien.

    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

    ¿alguien puede decir de mí: ¿hay algún lugar específico donde el archivo pdf se va a colocar??

  12. 1

    Sólo si todavía alguien lo necesita: Cómo imprimir el HTML a partir de un PDF con 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)
  13. 1

    Este trabajó para mí en python 3.
    Se requiere la PDFMiner.seis paquete

    pip install pdfminer.six

    El código es el siguiente (el mismo código como todo el mundo, con correcciones menores):

    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    from pdfminer.converter import TextConverter
    from pdfminer.layout import LAParams
    from pdfminer.pdfpage import PDFPage
    from six 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 = 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)
        fp.close()
        device.close()
        str = retstr.getvalue()
        retstr.close()
    
        return str.replace("\\n","\n")
  14. 0

    Los siguientes fragmentos de código es capaz de extraer texto de documentos pdf usando la última versión de pdfminer(23-Mar-2016). Espero que esto ayude.

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

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea