Skip to content

Perfiles de extracción — ajusta la detección de espacios por tipo de documento

Cada PDF esconde sus espacios de manera distinta. Un paper de arXiv usa columnas justificadas y apretadas. Un formulario del IRS depende de una alineación rígida de celdas. Una política GDPR se despliega como párrafos densos y justificados con un kerning mínimo. Un único tj_offset_threshold que funciona para uno de esos casos va a meter espacios basura en los otros.

ExtractionProfile trae nueve conjuntos de parámetros preajustados que encajan con clases reales de documento. Pasa el perfil a extract_text() o extract_words() y PDF Oxide aplica la proporción de margen de palabra correcta, el umbral de offset TJ correcto y el interruptor de umbral adaptativo correcto para ese estilo de documento.

Cobertura por binding. Los perfiles de extracción están disponibles actualmente en Python (pdf_oxide.ExtractionProfile) y Rust (pdf_oxide::config::ExtractionProfile). Los bindings de Node, WASM, Go y C# usan internamente el valor por defecto CONSERVATIVE; para aplicar otro perfil desde esos runtimes, invoca la CLI de Rust (pdf-oxide extract --profile academic doc.pdf) o puentea a través de un paso en Python o Rust.

Ejemplo rápido

Python

from pdf_oxide import PdfDocument, ExtractionProfile

doc = PdfDocument("paper.pdf")

# Papers académicos: espaciado compacto, detección de citas activa
text = doc.extract_text(0, profile=ExtractionProfile.academic())
print(text)

Rust

use pdf_oxide::PdfDocument;
use pdf_oxide::config::ExtractionProfile;

let mut doc = PdfDocument::open("paper.pdf")?;
let text = doc.extract_text_with_profile(0, ExtractionProfile::ACADEMIC)?;
println!("{}", text);

Perfiles disponibles

Perfil Ideal para Umbral TJ Margen de palabra Adaptativo
conservative() Default — texto general, mínimos falsos espacios −120 0,10 off
aggressive() PDFs que omiten espacios; une palabras pegadas −80 0,20 off
balanced() Contenido mixto −100 0,15 off
academic() Papers arXiv, actas de conferencia, reportes técnicos −105 0,12 on + detección de citas / correos
policy() Legal, GDPR, regulaciones gubernamentales −110 0,18 on
form() Formularios IRS, solicitudes, cuestionarios −120 0,08 off
government() Reportes gubernamentales mixtos con tablas −105 0,14 off
scanned_ocr() Salida OCR con coordenadas ruidosas depende depende on
adaptive() Deja que el extractor se autoconfigure con las estadísticas de fuente depende depende on

Cuándo ayuda cada perfil

Papers académicos / conferencias — academic()

Composición apretada, dos columnas, citas embebidas. Los valores por defecto suelen meter espacios de más dentro de ligaduras (fi, ff) o de menos entre palabras donde el kerning es agresivo.

doc = PdfDocument("neurips-paper.pdf")
text = doc.extract_text(0, profile=ExtractionProfile.academic())

El perfil académico activa el umbral adaptativo y la detección de citas y correos, de modo que referencias en línea como [1,2,3] y correos como author@lab.edu quedan intactos.

Formularios IRS, solicitudes — form()

Los PDFs de formularios se preocupan por la alineación de columnas más que por los límites de palabra. El perfil form() usa una proporción de margen de palabra muy ajustada (0,08) para que las etiquetas de campo rígidamente alineadas no se fundan con sus valores.

doc = PdfDocument("w2.pdf")
text = doc.extract_text(0, profile=ExtractionProfile.form())

GDPR / políticas / regulación — policy()

Los párrafos justificados insertan espacios variables que rompen el umbral por defecto. policy() usa un margen de palabra más generoso (0,18) junto con umbral adaptativo para leer correctamente la prosa legal densa.

doc = PdfDocument("gdpr.pdf")
text = doc.extract_text(0, profile=ExtractionProfile.policy())

Salida OCR escaneada — scanned_ocr()

Cuando la página viene de OCR (Tesseract, PaddleOCR, Azure), las posiciones de los caracteres son ruidosas y faltan las pistas de kerning. scanned_ocr() compensa con un umbral adaptativo que relee las estadísticas de fuente por página.

doc = PdfDocument("scanned.pdf")
text = doc.extract_text(0, profile=ExtractionProfile.scanned_ocr())

Dejar que la biblioteca elija — adaptive()

Si no sabes de antemano la clase del documento, adaptive() muestrea las estadísticas de fuente en la primera pasada y elige umbrales antes de extraer. Es un poco más lento que un perfil fijo pero aguanta bien los corpus mixtos.

for pdf_path in Path("mixed_corpus/").glob("*.pdf"):
    doc = PdfDocument(str(pdf_path))
    text = doc.extract_text(0, profile=ExtractionProfile.adaptive())

Campos del perfil

Cada perfil expone sus perillas de ajuste para que puedas leerlas o clonarlas:

Python

from pdf_oxide import ExtractionProfile

p = ExtractionProfile.academic()
print(p.name)                # "Academic"
print(p.word_margin_ratio)   # 0.12
print(p.tj_offset_threshold) # -105.0

# Inspecciona todos los presets
for profile in ExtractionProfile.all_profiles():
    print(profile.name, profile.word_margin_ratio)

Rust

use pdf_oxide::config::ExtractionProfile;

let p = ExtractionProfile::ACADEMIC;
println!("{} margin={} tj={}",
    p.name, p.word_margin_ratio, p.tj_offset_threshold);

Elegir un perfil en pipelines de producción

Si ingieres un corpus mixto — papers académicos junto a formularios del IRS junto a HTML exportado de la web — elige adaptive() como default. Cuesta un pequeño porcentaje por página, pero elimina los peores fallos (palabras pegadas, espacios perdidos entre columnas).

Si tu corpus es homogéneo — un pipeline de ingesta Title IX, una herramienta de revisión de contratos o un crawler de arXiv — elige el perfil que corresponda de forma explícita: vas a conseguir la mejor calidad de extracción y te ahorras el costo de muestreo por página de adaptive().

Páginas relacionadas