Parsing dei PDF con PyMuPDF e pdfplumber
Estrazione programmatica di testo, tabelle e metadati dai PDF
Parsing dei PDF con PyMuPDF e pdfplumber è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.
Perché l'analisi dei PDF non è banale
I PDF sono un formato per la presentazione, non per i dati. Il testo viene memorizzato come glifi posizionati, non come paragrafi logici. L'estrazione di testo significativo richiede la comprensione del layout, dell'ordine di lettura e delle proprietà dei caratteri, oltre alla gestione di casi limite come layout a più colonne, intestazioni e piè di pagina e immagini incorporate.
Le due librerie principali sono: PyMuPDF (velocità) e pdfplumber (estrazione delle tabelle).
Nozioni di base su PyMuPDF
PyMuPDF (importato come fitz) è la libreria Python più veloce per i PDF. Gestisce l'estrazione del testo, i metadati, le immagini e il rendering. Installi 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])Modalità di estrazione del testo di PyMuPDF
page.get_text() supporta diversi formati di output. Utilizzi 'text' per il testo semplice, 'blocks' per i blocchi di testo con riquadri di delimitazione e 'dict' per un output strutturato completo che include nomi e dimensioni dei caratteri.
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()Estrazione dei metadati delle pagine
I metadati delle pagine aiutano gli agenti a comprendere la struttura del documento: numero di pagine, titolo del documento, autore, data di creazione e dimensioni delle pagine. PyMuPDF mette a disposizione tutte queste informazioni.
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 per l'estrazione delle tabelle
pdfplumber è particolarmente efficace nell'estrazione delle tabelle dai PDF. Utilizza l'analisi geometrica per rilevare i confini delle celle, anche nei PDF privi di un markup esplicito per le tabelle.
Installi 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)Impostazioni delle tabelle di pdfplumber
L'estrazione delle tabelle di pdfplumber può essere configurata con impostazioni che gestiscono diversi stili di tabella: linee esplicite, colonne separate da spazi o layout misti.
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])Gestione dei layout a più colonne
Gli articoli accademici e i giornali utilizzano layout a più colonne. L'estrazione ingenua del testo legge da sinistra a destra attraverso le colonne, producendo testo senza senso. Risolva il problema ordinando prima i blocchi di testo per colonna.
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_textFiltraggio di intestazioni e piè di pagina
Le intestazioni e i piè di pagina dei PDF si ripetono su ogni pagina e inquinano il testo estratto. Li individui in base alla posizione verticale (nel 10% superiore o inferiore della pagina) ed escluda dall'estrazione del contenuto.
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)Suddivisione del testo dei PDF per gli agenti
I PDF lunghi devono essere suddivisi in segmenti per l'embedding e il recupero. Suddivida il testo in corrispondenza di confini naturali: paragrafi, sezioni o pagine. Includa una sovrapposizione tra i segmenti per evitare di interrompere il contesto a metà frase.
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]}')Combinare PyMuPDF e pdfplumber
Utilizzi PyMuPDF per l'estrazione del testo (più veloce) e pdfplumber per il rilevamento delle tabelle (più accurato). Un estrattore combinato esegue entrambe le operazioni su ogni pagina e restituisce contenuti strutturati, con testo e tabelle separati.
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 resultSalvare il testo estratto nei file
Dopo aver estratto il testo dai PDF, lo salvi in un formato che gli agenti nelle fasi successive possano utilizzare. I file di testo semplice funzionano bene nelle pipeline di embedding; JSON conserva la struttura delle pagine per il tracciamento delle citazioni.
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', '.')Verifica delle conoscenze
Quale libreria Python è più adatta per estrarre tabelle dai file PDF?
Riepilogo: analisi dei PDF con PyMuPDF e pdfplumber
PyMuPDF (fitz) è la scelta più veloce per l'estrazione del testo, dei metadati e la gestione dei layout a più colonne. pdfplumber eccelle nell'estrazione delle tabelle grazie a strategie geometriche configurabili.
Tecniche chiave: utilizzi get_text('blocks') per un'estrazione basata sulla posizione, filtri le intestazioni e i piè di pagina in base alla posizione verticale, gestisca i layout a più colonne ordinando i blocchi per colonna e suddivida il testo in segmenti sovrapposti per i sistemi di recupero degli agenti. Combini entrambe le librerie per ottenere i risultati migliori.
Domande Frequenti
La lezione «Parsing dei PDF con PyMuPDF e pdfplumber» è gratuita?
Sì — il testo completo di «Parsing dei PDF con PyMuPDF e pdfplumber» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.
Cosa imparerò in «Parsing dei PDF con PyMuPDF e pdfplumber»?
Estrazione programmatica di testo, tabelle e metadati dai PDF Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Agents?
Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Parsing dei PDF con PyMuPDF e pdfplumber»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Agents?
Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Parsing dei PDF con PyMuPDF e pdfplumber
- OCR per documenti scansionati
- Agenti Q&A su più documenti
- Classificazione e instradamento dei documenti