Skip to content

Perfis de extração — ajuste a detecção de espaços por tipo de documento

PDFs diferentes escondem os espaços de formas diferentes. Um artigo do arXiv usa colunas justificadas e apertadas. Um formulário do IRS depende de alinhamento rígido de células. Uma política GDPR se espalha em parágrafos densos e justificados com kerning mínimo. Um único tj_offset_threshold que funciona para um desses casos vai injetar espaços falsos nos outros.

ExtractionProfile traz nove conjuntos de parâmetros pré-ajustados que mapeiam direto em classes reais de documento. Passe o perfil para extract_text() ou extract_words() e o PDF Oxide aplica a razão de margem de palavra, o threshold de offset TJ e o flag de threshold adaptativo adequados para aquele estilo de documento.

Cobertura por binding. Os perfis de extração estão expostos atualmente em Python (pdf_oxide.ExtractionProfile) e Rust (pdf_oxide::config::ExtractionProfile). Os bindings de Node, WASM, Go e C# usam internamente o padrão CONSERVATIVE; para aplicar outro perfil a partir desses runtimes, invoque a CLI em Rust (pdf-oxide extract --profile academic doc.pdf) ou encadeie com uma etapa em Python / Rust.

Exemplo rápido

Python

from pdf_oxide import PdfDocument, ExtractionProfile

doc = PdfDocument("paper.pdf")

# Artigos acadêmicos: espaçamento apertado, detecção de citações ligada
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);

Perfis disponíveis

Perfil Melhor para Threshold TJ Razão de margem de palavra Adaptativo
conservative() Padrão — texto geral, mínimo de espaços falsos −120 0,10 off
aggressive() PDFs que suprimem espaços; corrige palavras coladas −80 0,20 off
balanced() Conteúdo misto −100 0,15 off
academic() Artigos do arXiv, anais de conferência, relatórios técnicos −105 0,12 on + detecção de citações / e-mails
policy() Legal, GDPR, regulamentações governamentais −110 0,18 on
form() Formulários IRS, requerimentos, questionários −120 0,08 off
government() Relatórios governamentais mistos com tabelas −105 0,14 off
scanned_ocr() Saída de OCR com coordenadas ruidosas depende depende on
adaptive() Deixa o extrator se ajustar a partir das estatísticas da fonte depende depende on

Quando cada perfil ajuda

Artigos acadêmicos / conferência — academic()

Composição apertada, layouts de duas colunas, citações embutidas. As configurações padrão costumam inserir espaços a mais dentro de ligaduras (fi, ff) ou a menos entre palavras onde o kerning é agressivo.

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

O perfil acadêmico liga o threshold adaptativo junto com a detecção de citações e e-mails, de modo que referências inline [1,2,3] e e-mails como author@lab.edu sobrevivem limpos.

Formulários IRS, requerimentos — form()

PDFs de formulário se importam mais com o alinhamento das colunas do que com os limites entre palavras. O perfil form() usa uma razão de margem de palavra bem apertada (0,08) para que rótulos de campo rigidamente alinhados não colapsem com os valores.

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

GDPR / políticas / regulação — policy()

Parágrafos justificados inserem espaçamento variável que quebra o threshold padrão. policy() usa uma margem de palavra mais generosa (0,18) com threshold adaptativo para ler corretamente textos jurídicos densos.

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

Saída de OCR digitalizada — scanned_ocr()

Quando a página passou por OCR (Tesseract, PaddleOCR, Azure), as posições dos caracteres ficam ruidosas e as dicas de kerning somem. scanned_ocr() compensa com threshold adaptativo que relê as estatísticas da fonte a cada página.

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

Deixe a biblioteca escolher — adaptive()

Se você não sabe de antemão a classe do documento, adaptive() faz uma amostragem das estatísticas da fonte na primeira passada e define os thresholds antes de extrair. Um pouco mais lento do que um perfil fixo, mas tolerante em corpus mistos.

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

Campos do perfil

Cada perfil expõe seus ajustes para você ler ou clonar:

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

# Inspecionar todos os 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);

Escolhendo um perfil em pipelines de produção

Se você ingere um corpus misto — artigos acadêmicos ao lado de formulários IRS ao lado de exports HTML raspados da web — escolha adaptive() como padrão. Custa um pouco a mais por página, mas elimina as piores falhas (palavras coladas, espaços ausentes entre colunas).

Se o seu corpus é homogêneo — uma pipeline de intake de Title IX, uma ferramenta de revisão contratual, um crawler de arXiv — escolha o perfil correspondente explicitamente: você obtém a melhor qualidade de extração e evita o custo de amostragem por página do adaptive().

Páginas relacionadas