Análisis de PDF con PyMuPDF y pdfplumber
Extraiga texto, tablas y metadatos de archivos PDF mediante programación.
Análisis de PDF con PyMuPDF y pdfplumber es una lección gratuita de AI Agents en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Agents, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Agents incluye 4 lecciones en total.
Por qué analizar archivos PDF no es sencillo
Los PDF son un formato de presentación, no un formato de datos. El texto se almacena como glifos posicionados, no como párrafos lógicos. Extraer texto con significado requiere comprender el diseño, el orden de lectura y las propiedades de las fuentes, además de gestionar casos límite como diseños con varias columnas, encabezados y pies de página e imágenes incrustadas.
Dos bibliotecas son las más utilizadas: PyMuPDF (velocidad) y pdfplumber (extracción de tablas).
Conceptos básicos de PyMuPDF
PyMuPDF (que se importa como fitz) es la biblioteca de Python más rápida para trabajar con PDF. Permite extraer texto, metadatos e imágenes, además de renderizar documentos. Instálela con pip install pymupdf.
import fitz # PyMuPDF
# Open a PDF
doc = fitz.open('document.pdf')
print(f'Pages: {len(doc)}')
print(f'Metadata: {doc.metadata}')
# Extract text from all pages
full_text = ''
for page_num in range(len(doc)):
page = doc[page_num]
text = page.get_text() # plain text extraction
full_text += f'--- Page {page_num + 1} ---\n{text}\n'
doc.close()
print(full_text[:500])Modos de extracción de texto de PyMuPDF
page.get_text() admite distintos formatos de salida. Utilice 'text' para texto sin formato, 'blocks' para bloques de texto con cuadros delimitadores y 'dict' para una salida estructurada enriquecida que incluya los nombres y tamaños de las fuentes.
import fitz
doc = fitz.open('report.pdf')
page = doc[0]
# Mode 1: plain text
plain = page.get_text('text')
# Mode 2: blocks (each block has bbox + text)
blocks = page.get_text('blocks')
for block in blocks:
x0, y0, x1, y1, text, block_no, block_type = block
if block_type == 0: # text block (1 = image)
print(f'Block at ({x0:.0f},{y0:.0f}): {text[:80]}')
# Mode 3: dict (full detail including font info)
page_dict = page.get_text('dict')
for block in page_dict['blocks']:
if block.get('type') == 0: # text
for line in block['lines']:
for span in line['spans']:
print(f"Font: {span['font']}, Size: {span['size']:.1f}, Text: {span['text']}")
doc.close()Extracción de metadatos de las páginas
Los metadatos de las páginas ayudan a los agentes a comprender la estructura del documento: número de páginas, título del documento, autor, fecha de creación y dimensiones de las páginas. PyMuPDF proporciona toda esta información.
import fitz
def extract_pdf_metadata(filepath):
doc = fitz.open(filepath)
meta = doc.metadata
info = {
'title': meta.get('title', 'Unknown'),
'author': meta.get('author', 'Unknown'),
'subject': meta.get('subject', ''),
'creator': meta.get('creator', ''),
'created': meta.get('creationDate', ''),
'modified': meta.get('modDate', ''),
'pages': len(doc),
'page_size': {
'width': doc[0].rect.width,
'height': doc[0].rect.height
}
}
doc.close()
return info
meta = extract_pdf_metadata('contract.pdf')
print(f"Title: {meta['title']}, Pages: {meta['pages']}")pdfplumber para extraer tablas
pdfplumber destaca en la extracción de tablas de archivos PDF. Utiliza análisis geométrico para detectar los límites de las celdas, incluso en PDF que no contienen un marcado explícito de tablas.
Instálelo con pip install pdfplumber.
import pdfplumber
with pdfplumber.open('financial_report.pdf') as pdf:
for page_num, page in enumerate(pdf.pages):
tables = page.extract_tables()
for table_idx, table in enumerate(tables):
print(f'Page {page_num+1}, Table {table_idx+1}:')
# table is a list of rows; each row is a list of cell strings
headers = table[0]
for row in table[1:]:
row_dict = dict(zip(headers, row))
print(row_dict)Configuración de tablas en pdfplumber
La extracción de tablas de pdfplumber se puede ajustar mediante opciones para gestionar distintos estilos de tabla: líneas explícitas, columnas separadas por espacios o diseños mixtos.
import pdfplumber
# Custom table settings for borderless tables
table_settings = {
'vertical_strategy': 'text', # 'lines', 'lines_strict', 'text', 'explicit'
'horizontal_strategy': 'text',
'snap_tolerance': 5,
'join_tolerance': 3,
'edge_min_length': 50,
'min_words_vertical': 3,
'min_words_horizontal': 1
}
with pdfplumber.open('nolines_table.pdf') as pdf:
page = pdf.pages[0]
table = page.extract_table(table_settings)
if table:
import csv
import io
output = io.StringIO()
writer = csv.writer(output)
writer.writerows(table)
csv_string = output.getvalue()
print(csv_string[:300])Gestión de diseños con varias columnas
Los artículos académicos y los periódicos utilizan diseños con varias columnas. La extracción de texto ingenua lee de izquierda a derecha atravesando las columnas, lo que produce texto ilegible. Corrija este problema ordenando primero los bloques de texto por columna.
import fitz
def extract_multicolumn_text(page, n_columns=2):
page_width = page.rect.width
col_width = page_width / n_columns
blocks = page.get_text('blocks')
# Filter text blocks only
text_blocks = [b for b in blocks if b[6] == 0]
# Assign each block to a column based on x position
columns = [[] for _ in range(n_columns)]
for block in text_blocks:
x0 = block[0]
col_idx = min(int(x0 / col_width), n_columns - 1)
columns[col_idx].append(block)
# Sort each column by vertical position
for col in columns:
col.sort(key=lambda b: b[1]) # sort by y0
# Read columns left to right
full_text = ''
for col in columns:
for block in col:
full_text += block[4] + '\n'
return full_textFiltrado de encabezados y pies de página
Los encabezados y pies de página de los PDF se repiten en todas las páginas y contaminan el texto extraído. Identifíquelos por su posición vertical (el 10 % superior o inferior de la página) y exclúyalos de la extracción de contenido.
import fitz
def extract_without_headers_footers(page, margin_ratio=0.08):
page_height = page.rect.height
top_margin = page_height * margin_ratio
bottom_margin = page_height * (1 - margin_ratio)
blocks = page.get_text('blocks')
content_blocks = []
for block in blocks:
x0, y0, x1, y1, text, block_no, block_type = block
if block_type != 0:
continue # skip image blocks
# Skip blocks in header or footer zone
if y0 < top_margin or y1 > bottom_margin:
continue
content_blocks.append(text)
return '\n'.join(content_blocks)Segmentación de texto PDF para agentes
Los PDF largos deben dividirse en fragmentos para generar embeddings y realizar búsquedas. Divida el contenido en límites naturales: párrafos, secciones o páginas. Incluya solapamiento entre los fragmentos para evitar cortar el contexto a mitad de una oración.
import fitz
def pdf_to_chunks(filepath, chunk_size=1000, overlap=200):
doc = fitz.open(filepath)
chunks = []
for page_num in range(len(doc)):
page = doc[page_num]
page_text = page.get_text()
# Split into chunks with overlap
start = 0
while start < len(page_text):
end = start + chunk_size
chunk = page_text[start:end]
chunks.append({
'text': chunk,
'page': page_num + 1,
'char_start': start,
'source': filepath
})
start += chunk_size - overlap # overlap
doc.close()
return chunks
chunks = pdf_to_chunks('research_paper.pdf')
print(f'Total chunks: {len(chunks)}')
print(f'Sample: {chunks[0]["text"][:200]}')Combinación de PyMuPDF y pdfplumber
Use PyMuPDF para extraer texto (es más rápido) y pdfplumber para detectar tablas (es más preciso). Un extractor combinado ejecuta ambas bibliotecas en cada página y devuelve contenido estructurado, con el texto y las tablas separados.
import fitz
import pdfplumber
def full_pdf_extract(filepath):
result = {'text_by_page': [], 'tables': []}
# Text extraction with PyMuPDF
doc = fitz.open(filepath)
for i in range(len(doc)):
text = extract_without_headers_footers(doc[i])
result['text_by_page'].append({'page': i + 1, 'text': text})
doc.close()
# Table extraction with pdfplumber
with pdfplumber.open(filepath) as pdf:
for page_num, page in enumerate(pdf.pages):
tables = page.extract_tables()
for t in tables:
result['tables'].append({
'page': page_num + 1,
'headers': t[0] if t else [],
'rows': t[1:] if t and len(t) > 1 else []
})
return resultGuardado del texto extraído en archivos
Después de extraer texto de los PDF, guárdelo en un formato que los agentes posteriores puedan procesar. Los archivos de texto sin formato funcionan bien en los pipelines de embeddings; JSON conserva la estructura de las páginas para realizar el seguimiento de las citas.
import json, os
class FakePage:
def __init__(self, text): self.text = text
def get_text(self): return self.text
class FakeDoc(list):
def close(self): pass
def fitz_open(path):
return FakeDoc([FakePage('Page 1 text'), FakePage('Page 2 text')])
def pdf_to_text_file(pdf_path, output_dir):
doc = fitz_open(pdf_path)
base = os.path.splitext(os.path.basename(pdf_path))[0]
txt_path = os.path.join(output_dir, base + '.txt')
with open(txt_path, 'w', encoding='utf-8') as f:
for i, page in enumerate(doc):
f.write(f'--- Page {i+1} ---\n{page.get_text()}\n')
json_path = os.path.join(output_dir, base + '.json')
pages = [{'page': i+1, 'text': p.get_text()} for i, p in enumerate(doc)]
with open(json_path, 'w') as f:
json.dump({'source': pdf_path, 'pages': pages}, f, indent=2)
doc.close()
print(f'Saved: {txt_path} and {json_path}')
return txt_path, json_path
pdf_to_text_file('sample.pdf', '.')Comprobación de conocimientos
¿Qué biblioteca de Python es la más adecuada para extraer tablas de archivos PDF?
Resumen: análisis de PDF con PyMuPDF y pdfplumber
PyMuPDF (fitz) es la opción rápida para extraer texto y metadatos, así como para gestionar diseños de varias columnas. pdfplumber destaca en la extracción de tablas gracias a sus estrategias geométricas configurables.
Técnicas clave: use get_text('blocks') para extraer contenido teniendo en cuenta su posición, filtre los encabezados y pies de página según su posición vertical, gestione los diseños de varias columnas ordenando los bloques por columna y divida el texto en fragmentos con solapamiento para los sistemas de recuperación de agentes. Combine ambas bibliotecas para obtener los mejores resultados.
Preguntas frecuentes
¿La lección «Análisis de PDF con PyMuPDF y pdfplumber» es gratis?
Sí — el texto completo de «Análisis de PDF con PyMuPDF y pdfplumber» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Agents, actualiza a CoddyKit PRO. El curso de AI Agents incluye 4 lecciones en total.
¿Qué aprenderé en «Análisis de PDF con PyMuPDF y pdfplumber»?
Extraiga texto, tablas y metadatos de archivos PDF mediante programación. Practicas AI Agents con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar AI Agents?
No se requiere experiencia previa. AI Agents en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Análisis de PDF con PyMuPDF y pdfplumber»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de AI Agents?
Sí. Cada lección de AI Agents incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Análisis de PDF con PyMuPDF y pdfplumber
- OCR para documentos escaneados
- Agentes de preguntas y respuestas sobre varios documentos
- Clasificación y enrutamiento de documentos