Breaking

Post Top Ad

Your Ad Spot

viernes, 14 de junio de 2019

Trabajar con archivos PDF en Python: leer y dividir páginas

Este artículo es el primero de una serie sobre el trabajo con archivos PDF en Python:

El formato de documento PDF

Hoy en día, el Formato de Documento Portátil (PDF) pertenece a los formatos de datos más utilizados. En 1990, la estructura de un documento PDF fue definida por Adobe. La idea detrás del formato PDF es que los datos / documentos transmitidos se ven exactamente iguales para las dos partes involucradas en el proceso de comunicación: el creador, el autor o el remitente y el receptor. PDF es el sucesor del formato PostScript y está estandarizado como ISO 32000-2: 2017 .

Procesamiento de documentos PDF

Para Linux hay poderosas herramientas de línea de comandos disponibles, como pdftk y pdfgrep . Como desarrollador, existe una gran emoción al crear su propio software que se basa en Python y utiliza bibliotecas PDF que están disponibles gratuitamente.
Este artículo es el comienzo de una pequeña serie y cubrirá estas bibliotecas útiles de Python. En la primera parte nos centraremos en la manipulación de archivos PDF existentes. Aprenderá cómo leer y extraer el contenido (texto e imágenes), rotar páginas individuales y dividir documentos en sus páginas individuales. La segunda parte cubrirá la adición de una marca de agua basada en superposiciones. La tercera parte se centrará exclusivamente en escribir / crear archivos PDF, y también incluirá tanto la eliminación como la combinación de páginas individuales en un nuevo documento.

Herramientas y bibliotecas

El rango de soluciones disponibles para herramientas, módulos y bibliotecas PDF relacionadas con Python es un poco confuso, y toma un momento averiguar qué es qué y qué proyectos se mantienen continuamente. Basados ​​en nuestra investigación, estos son los candidatos que están actualizados:
  • PyPDF2 : una biblioteca de Python para extraer información y contenido del documento, dividir documentos página por página, combinar documentos, recortar páginas y agregar marcas de agua. PyPDF2 admite tanto documentos sin cifrar como cifrados.
  • PDFMiner : está escrito completamente en Python y funciona bien para Python 2.4. Para Python 3, use el paquete clonado PDFMiner.six . Ambos paquetes le permiten analizar, analizar y convertir documentos PDF. Esto incluye el soporte para PDF 1.7, así como los idiomas CJK (chino, japonés y coreano), y varios tipos de fuentes (Type1, TrueType, Type3 y CID).
  • PDFQuery : se describe a sí mismo como "una biblioteca de raspado de PDF rápida y fácil de usar" que se implementa como un envoltorio alrededor de PDFMiner, lxml y pyquery . Su objetivo de diseño es "extraer datos de forma confiable de conjuntos de archivos PDF con el menor código posible".
  • tabula-py : es un simple envoltorio Python de tabula-java , que puede leer tablas de archivos PDF y convertirlas en Pandas DataFrames. También le permite convertir un archivo PDF en un archivo CSV / TSV / JSON.
  • pdflib para Python: una extensión de la biblioteca Poppler que ofrece enlaces de Python para ella. Te permite analizar, analizar y convertir documentos PDF. No debe confundirse con su colgante comercial que tiene el mismo nombre.
  • PyFPDF : una biblioteca para la generación de documentos PDF en Python. Portado desde la biblioteca PHP FPDF , un conocido reemplazo de extensión PDFlib con muchos ejemplos, scripts y derivados.
  • Tablas de PDF : un servicio comercial que ofrece extracción de tablas que viene como un documento PDF. Ofrece una API para que los PDFTables puedan usarse como SAAS.
  • PyX : el paquete de gráficos de Python: PyX es un paquete de Python para la creación de archivos PostScript, PDF y SVG. Combina una abstracción del modelo de dibujo PostScript con una interfaz TeX / LaTeX. Las tareas complejas, como la creación de gráficos en 2D y 3D en calidad lista para publicación, se construyen a partir de estas primitivas.
  • ReportLab : una biblioteca ambiciosa de gran fortaleza industrial centrada en gran medida en la creación precisa de documentos PDF. Disponible libremente como una versión de código abierto, así como una versión comercial mejorada llamada ReportLab PLUS.
  • PyMuPDF (también conocido como "fitz"): enlaces Python para MuPDF, que es un visor de PDF y XPS ligero. La biblioteca puede acceder a archivos en formato PDF, XPS, OpenXPS, epub, cómics y libros de ficción, y es conocida por su alto rendimiento y alta calidad de representación.
  • pdfrw : un analizador de PDF basado en Python para leer y escribir PDF. Reproduce fielmente formatos vectoriales sin rasterización. Junto con ReportLab, es útil reutilizar partes de PDF existentes en nuevos PDF creados con ReportLab.
BibliotecaUsado para
PyPDF2Leyendo
PyMuPDFLeyendo
pdflibLeyendo
Tablas PDFLeyendo
tabula-pyLeyendo
PDFMiner.sixLeyendo
PDFQueryLeyendo
pdfrwLeer, escribir / crear
ReportlabEscritura / Creación
PíxideEscritura / Creación
PyFPDFEscritura / Creación
A continuación, nos centraremos en PyPDF2 y PyMuPDF, y explicaremos cómo extraer texto e imágenes de la forma más sencilla posible. Para comprender el uso de PyPDF2, se ha ayudado con una combinación de la documentación oficial y muchos ejemplos disponibles de otros recursos. En contraste, la documentación oficial de PyMuPDF es mucho más clara y considerablemente más rápida utilizando la biblioteca.

Extraer texto con PyPDF2

PyPDF2 se puede instalar como un paquete de software regular, o usar pip3(para Python3). Las pruebas aquí se basan en el paquete para el próximo Debian GNU / Linux versión 10 "Buster". El nombre del paquete Debian es python3-pypdf2.
El Listado 1 importa la PdfFileReaderclase, primero. A continuación, utilizando esta clase, abre el documento y extrae la información del documento mediante el getDocumentInfo()método, la cantidad de páginas que se utilizan getDocumentInfo()y el contenido de la primera página.
Tenga en cuenta que PyPDF2 comienza a contar las páginas con 0, y es por eso que la llamada pdf.getPage(0)recupera la primera página del documento. Eventualmente, la información extraída se imprime en stdout.
Listado 1: Extraer la información y el contenido del documento.
#!/usr/bin/python

from PyPDF2 import PdfFileReader

pdf_document = "example.pdf"  
with open(pdf_document, "rb") as filehandle:  
    pdf = PdfFileReader(filehandle)
    info = pdf.getDocumentInfo()
    pages = pdf.getNumPages()

    print (info)
    print ("number of pages: %i" % pages)

    page1 = pdf.getPage(0)
    print(page1)
    print(page1.extractText())
Fig. 1: Texto extraído de un archivo PDF utilizando PyPDF2
Fig. 1: Texto extraído de un archivo PDF utilizando PyPDF2
Como se muestra en la Figura 1 anterior, el texto extraído se imprime de manera continua. No hay párrafos, ni separaciones de oraciones. Como se indica en la documentación de PyPDF2, todos los datos de texto se devuelven en el orden en que se proporcionan en el flujo de contenido de la página, y confiar en ellos puede llevar a algunas sorpresas. Esto depende principalmente de la estructura interna del documento PDF y de cómo el proceso de escritura de PDF produjo la secuencia de instrucciones PDF.

Extraer texto con PyMuPDF

PyMuPDF está disponible en el sitio web de PyPi e instala el paquete con el siguiente comando en un terminal:
$ pip3 install PyMuPDF
La visualización de la información del documento, la impresión del número de páginas y la extracción del texto de un documento PDF se realiza de forma similar a la de PyPDF2 (consulte el Listado 2 ). El módulo que se va a importar tiene un nombre fitzy vuelve al nombre anterior de PyMuPDF.
Listado 2: extracción de contenido de un documento PDF utilizando PyMuPDF.
#!/usr/bin/python

import fitz

pdf_document = "example.pdf"  
doc = fitz.open(pdf_document):  
print ("number of pages: %i" % doc.pageCount)  
print(doc.metadata)

page1 = doc.loadPage(0)  
page1text = page1.getText("text")  
print(page1text)  
Lo bueno de PyMuPDF es que mantiene intacta la estructura del documento original: los párrafos completos con saltos de línea se mantienen tal como están en el documento PDF (consulte la Figura 2).
Fig. 2: Datos extraídos del texto.
Fig. 2: Datos extraídos del texto.

Extraer imágenes de archivos PDF con PyMuPDF

PyMuPDF simplifica la extracción de imágenes de documentos PDF utilizando el método getPageImageList()El Listado 3 se basa en un ejemplo de la página wiki de PyMuPDF y extrae y guarda todas las imágenes del PDF como archivos PNG página por página. Si una imagen tiene un espacio de color CMYK, primero se convertirá a RGB.
Listado 3: Extraer imágenes.
#!/usr/bin/python

import fitz

pdf_document = fitz.open("file.pdf")  
for current_page in range(len(pdf_document)):  
    for image in pdf_document.getPageImageList(current_page):
        xref = image[0]
        pix = fitz.Pixmap(pdf_document, xref)
        if pix.n < 5:        # this is GRAY or RGB
            pix.writePNG("page%s-%s.png" % (current_page, xref))
        else:                # CMYK: convert to RGB first
            pix1 = fitz.Pixmap(fitz.csRGB, pix)
            pix1.writePNG("page%s-%s.png" % (current_page, xref))
            pix1 = None
        pix = None
Al ejecutar este script Python en un PDF de 400 páginas, extrajo 117 imágenes en menos de 3 segundos, lo que es increíble. Las imágenes individuales se almacenan en formato PNG. Para mantener el formato y el tamaño de la imagen original, en lugar de convertir a PNG, eche un vistazo a las versiones extendidas de los scripts en la wiki de PyMuPDF .
Fig. 3: Imágenes extraídas.
Fig. 3: Imágenes extraídas.

Dividir archivos PDF en páginas con PyPDF2

Para este ejemplo, primero se deben importar PdfFileReaderlas PdfFileWriterclases y las clases. Luego abrimos el archivo PDF, creamos un objeto lector y recorramos todas las páginas utilizando el getNumPagesmétodo del objeto lector .
Dentro del forbucle, creamos una nueva instancia de PdfFileWriter, que aún no contiene ninguna página. Luego agregamos la página actual a nuestro objeto escritor usando el pdfWriter.addPage()método. Este método acepta un objeto de página, que obtenemos utilizando el PdfFileReader.getPage()método.
El siguiente paso es crear un nombre de archivo único, lo que hacemos al usar el nombre del archivo original más la palabra "página", más el número de la página. Agregamos 1 al número de página actual porque PyPDF2 cuenta los números de página comenzando en cero.
Finalmente, abrimos el nuevo nombre de archivo en modo "escribir binario" (modo wb), y usamos el write()método de la pdfWriterclase para guardar la página extraída en el disco.
Listado 4: División de un PDF en páginas individuales.
#!/usr/bin/python

from PyPDF2 import PdfFileReader, PdfFileWriter

pdf_document = "example.pdf"  
pdf = PdfFileReader(pdf_document)

for page in range(pdf.getNumPages()):  
    pdf_writer = PdfFileWriter
    current_page = pdf.getPage(page)
    pdf_writer.addPage(current_page)

    outputFilename = "example-page-{}.pdf".format(page + 1)
    with open(outputFilename, "wb") as out:
        pdf_writer.write(out)

        print("created", outputFilename)
Fig. 4: División de un PDF
Fig. 4: División de un PDF

Buscar todas las páginas que contienen texto

Este caso de uso es bastante práctico, y funciona de manera similar pdfgrepAl usar PyMuPDF, el script devuelve todos los números de página que contienen la cadena de búsqueda dada. Las páginas se cargan una tras otra y, con la ayuda del searchFor()método, se detectan todas las apariciones de la cadena de búsqueda. En caso de una coincidencia se imprime un mensaje correspondiente stdout.
Listado 5: Buscar un texto dado.
#!/usr/bin/python

import fitz

filename = "example.pdf"  
search_term = "invoice"  
pdf_document = fitz.open(filename):

for current_page in range(len(pdf_document)):  
    page = pdf_document.loadPage(current_page)
    if page.searchFor(search_term):
        print("%s found on page %i" % (search_term, current_page))
La figura 5 a continuación muestra el resultado de búsqueda del término "Debian GNU / Linux" en un libro de 400 páginas.
Fig. 5: Buscando un documento PDF
Fig. 5: Buscando un documento PDF

Conclusión

Los métodos que se muestran aquí son bastante poderosos. Con un número comparativamente pequeño de líneas de código, se obtiene fácilmente un resultado. Se examinan más casos de uso en la Parte Dos (¡próximamente!) Que cubre agregar una marca de agua a un PDF.

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Post Top Ad

Your Ad Spot

Páginas