Caricamento dei documenti ed estrazione del testo
Caricherà PDF, documenti Word e file di testo semplice usando librerie Python, pulirà il testo estratto e lo preparerà per la suddivisione in chunk e l'embedding.
Caricamento dei documenti ed estrazione del testo è una lezione AI Engineering Academy 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 Engineering Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Engineering Academy include 4 lezioni in totale.
Perché il caricamento dei documenti non è banale
La prima fase di qualsiasi pipeline RAG consiste nell'estrarre il testo grezzo dai documenti. Sembra semplice, ma nella pratica è sorprendentemente complesso. I file PDF possono contenere testo sotto forma di caratteri, immagini o una combinazione di entrambi. I documenti Word contengono markup di formattazione che deve essere rimosso. Le pagine HTML includono menu di navigazione e annunci pubblicitari insieme al contenuto effettivo. Un loader robusto deve gestire tutti questi casi e produrre testo pulito e coerente per il chunking.
Caricare PDF con pypdf
pypdf è la libreria Python standard per leggere file PDF che contengono testo incorporato. Estrae il testo pagina per pagina, preservando i confini originali delle pagine, che costituiscono metadati preziosi. Tuttavia, pypdf non può leggere i PDF acquisiti tramite scansione (immagini di testo): per questi è necessario l'OCR. Estragga sempre i numeri di pagina insieme al testo, così potrà citare la pagina esatta nelle citazioni RAG.
from pypdf import PdfReader
def load_pdf(file_path):
reader = PdfReader(file_path)
pages = []
for page_num, page in enumerate(reader.pages, start=1):
text = page.extract_text()
if text and text.strip(): # skip blank pages
pages.append({
'text': text,
'metadata': {
'source': file_path,
'page': page_num,
'doc_type': 'pdf'
}
})
return pages
docs = load_pdf('annual_report.pdf')
print(f'Loaded {len(docs)} non-empty pages')Caricare documenti Word con python-docx
I file Microsoft Word (.docx) memorizzano i contenuti in formato XML. La libreria python-docx analizza questo XML ed espone paragrafi, tabelle e intestazioni come oggetti Python. Estragga sequenzialmente il testo dei paragrafi e acquisisca i livelli delle intestazioni per preservare la struttura del documento: le intestazioni delle sezioni sono un contesto prezioso che migliora la qualità del chunking e del recupero quando vengono incluse insieme al testo che introducono.
from docx import Document
def load_docx(file_path):
doc = Document(file_path)
sections = []
current_section = {'heading': '', 'text': ''}
for para in doc.paragraphs:
if para.style.name.startswith('Heading'):
if current_section['text'].strip():
sections.append(current_section.copy())
current_section = {'heading': para.text, 'text': ''}
else:
current_section['text'] += para.text + '\n'
if current_section['text'].strip():
sections.append(current_section)
return [{'text': f"{s['heading']}\n{s['text']}",
'metadata': {'source': file_path, 'section': s['heading']}}
for s in sections]Caricare pagine web e HTML
Le pagine HTML contengono molto rumore: barre di navigazione, piè di pagina, banner dei cookie e blocchi pubblicitari. Utilizzi BeautifulSoup per analizzare l'HTML ed estrarre solo l'area del contenuto principale. Prenda di mira elementi come <article>, <main> o classi CSS specifiche del contenuto. Rimuova i tag script, style e nav prima di estrarre il testo, per evitare di inquinare i blocchi con codice JavaScript o voci di menu.
import requests
from bs4 import BeautifulSoup
def load_url(url):
response = requests.get(url, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
# Remove noise elements
for tag in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
tag.decompose()
# Try to find main content
main = soup.find('article') or soup.find('main') or soup.find('body')
text = main.get_text(separator='\n', strip=True)
return [{'text': text, 'metadata': {'source': url, 'doc_type': 'html'}}]Gestire i PDF acquisiti tramite scansione con l'OCR
I PDF scansionati memorizzano le pagine come immagini, senza testo incorporato. Per estrarre il testo è necessario usare il riconoscimento ottico dei caratteri (OCR). La libreria pytesseract integra il motore OCR Tesseract di Google. L'OCR è più lento e meno accurato dell'estrazione del testo (accuratezza dei caratteri dell'80-95% nelle scansioni di buona qualità), quindi preferisca sempre i PDF digitali quando disponibili. Indichi nei metadati che è stato usato l'OCR, così potrà esaminare le estrazioni con un basso livello di affidabilità.
import pytesseract
from pdf2image import convert_from_path
def load_scanned_pdf(file_path):
# Convert PDF pages to PIL images
pages_as_images = convert_from_path(file_path, dpi=300)
results = []
for page_num, img in enumerate(pages_as_images, start=1):
text = pytesseract.image_to_string(img, lang='eng')
results.append({
'text': text,
'metadata': {
'source': file_path,
'page': page_num,
'ocr': True # flag for quality review
}
})
return resultsUso di Unstructured per qualsiasi formato
La libreria unstructured è uno strumento versatile per il caricamento di documenti, in grado di gestire PDF, Word, Excel, PowerPoint, HTML, email e molto altro tramite un'API unificata. Utilizza euristiche per identificare gli elementi del documento (titolo, testo descrittivo, tabella, intestazione) e li restituisce come oggetti strutturati. È particolarmente utile quando il corpus contiene tipi di documenti misti e si desiderano metadati a livello di elemento senza scrivere parser specifici per ogni formato.
from unstructured.partition.auto import partition
def load_any_document(file_path):
elements = partition(filename=file_path)
docs = []
for element in elements:
docs.append({
'text': str(element),
'metadata': {
'source': file_path,
'element_type': type(element).__name__,
'category': element.category
}
})
return docs
# Works on .pdf, .docx, .pptx, .html, .eml, .xlsx
docs = load_any_document('presentation.pptx')Pulizia del testo dopo l'estrazione
Il testo estratto grezzo è raramente pulito. L'estrazione da PDF produce spesso interruzioni di riga con parole sillabate dovute ai layout a colonne, spazi bianchi superflui, intestazioni di pagina ripetute su ogni pagina e caratteri speciali alterati. Applichi una pipeline di pulizia: rimuova gli spazi bianchi eccessivi, ricomponga le parole sillabate attraverso le interruzioni di riga, elimini le intestazioni e i piè di pagina identificati tramite il confronto di pattern e normalizzi i caratteri Unicode. Un testo pulito porta a una coerenza dei chunk nettamente migliore.
import re
def clean_text(text):
# Rejoin hyphenated line breaks (PDF column artifacts)
text = re.sub(r'-(\n)([a-z])', r'\2', text)
# Normalize whitespace
text = re.sub(r' +', ' ', text)
text = re.sub(r'\n{3,}', '\n\n', text)
# Remove page numbers standing alone on a line
text = re.sub(r'^\d+$', '', text, flags=re.MULTILINE)
# Strip leading/trailing whitespace from each line
lines = [line.strip() for line in text.split('\n')]
return '\n'.join(lines).strip()Caricamento da database e API
Non tutta la conoscenza risiede nei file. Anche i database interni, i sistemi CRM, gli strumenti di ticketing e le API REST sono fonti di dati. Carichi le righe strutturate del database unendo le tabelle pertinenti e concatenando i valori dei campi in paragrafi in linguaggio naturale che il modello di embedding possa comprendere. Per le API, recuperi i risultati paginati e serializzi ogni record come documento di testo con coppie chiave-valore.
import psycopg2
def load_from_database(conn_string, query):
conn = psycopg2.connect(conn_string)
cursor = conn.cursor()
cursor.execute(query)
columns = [desc[0] for desc in cursor.description]
docs = []
for row in cursor.fetchall():
# Convert row to natural language text
parts = [f'{col}: {val}' for col, val in zip(columns, row) if val]
text = '\n'.join(parts)
docs.append({'text': text, 'metadata': {'source': 'database'}})
conn.close()
return docsTracciamento della provenienza dei documenti
Ogni documento caricato dovrebbe contenere metadati di provenienza per tutta la pipeline: URL o percorso del file di origine, titolo del documento, autore, data di creazione e data dell'ultima modifica. Questi metadati accompagnano ogni chunk nel vector store e vengono riportati nelle citazioni dell'LLM. Senza le informazioni di provenienza, non è possibile dire agli utenti da dove proviene una risposta, aggiornare documenti specifici nell'indice o filtrare il recupero in base agli attributi della fonte.
import os
from datetime import datetime
def load_pdf_with_provenance(file_path):
from pypdf import PdfReader
reader = PdfReader(file_path)
stat = os.stat(file_path)
base_metadata = {
'source': file_path,
'title': reader.metadata.get('/Title', os.path.basename(file_path)),
'author': reader.metadata.get('/Author', 'Unknown'),
'doc_type': 'pdf',
'file_size_kb': stat.st_size // 1024,
'loaded_at': datetime.utcnow().isoformat()
}
pages = []
for i, page in enumerate(reader.pages, 1):
text = page.extract_text()
if text and text.strip():
pages.append({'text': text, 'metadata': {**base_metadata, 'page': i}})
return pagesCaricamento in batch di grandi raccolte di documenti
Quando indicizza migliaia di documenti, li carichi in parallelo usando concurrent.futures per sfruttare al massimo le risorse di I/O e CPU. Implementi un indicatore di avanzamento e un registro degli errori, così i caricamenti non riusciti non elimineranno silenziosamente contenuti dall'indice. Non permetta mai che un singolo file danneggiato interrompa l'intero processo di caricamento: intercetti le eccezioni per ogni documento e continui con quello successivo.
from concurrent.futures import ThreadPoolExecutor, as_completed
def batch_load_documents(file_paths, max_workers=8):
all_docs = []
errors = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_path = {
executor.submit(load_pdf_with_provenance, p): p
for p in file_paths
}
for future in as_completed(future_to_path):
path = future_to_path[future]
try:
docs = future.result()
all_docs.extend(docs)
print(f'Loaded {len(docs)} pages from {path}')
except Exception as e:
errors.append({'path': path, 'error': str(e)})
return all_docs, errorsConvalida della qualità dei contenuti caricati
Dopo il caricamento, verifichi di aver estratto contenuti significativi. Controlli: la lunghezza minima del testo (ignori i chunk con meno di 50 caratteri), il rilevamento della lingua (se il suo sistema RAG è solo in inglese, filtri le pagine non in inglese) e il rilevamento del testo alterato (un'elevata proporzione di caratteri non ASCII può indicare un errore OCR o problemi di codifica). Registri statistiche come il numero di pagine caricate, la lunghezza media delle pagine e la percentuale di errori, per individuare tempestivamente i problemi di caricamento.
def validate_documents(docs, min_length=100):
valid = []
skipped = 0
for doc in docs:
text = doc['text']
if len(text) < min_length:
skipped += 1
continue
# Check for high non-ASCII ratio (garbled OCR)
non_ascii = sum(1 for c in text if ord(c) > 127)
if non_ascii / max(len(text), 1) > 0.3:
skipped += 1
continue
valid.append(doc)
print(f'Valid: {len(valid)}, Skipped: {skipped}')
return validVerifica rapida
Verifichi la sua comprensione dei concetti di AI Engineering trattati in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato a usare: loader specifici per formato per i PDF con pypdf, i documenti Word con python-docx, l'HTML con BeautifulSoup e i documenti scansionati con l'OCR; la libreria unstructured come loader unificato per più formati; e le best practice per la produzione, tra cui pulizia del testo, metadati di provenienza, caricamento batch parallelo e convalida dei contenuti. Prossimamente affronteremo le strategie di chunking, che determinano il modo in cui il testo recuperato viene associato al contesto del modello.
Domande Frequenti
La lezione «Caricamento dei documenti ed estrazione del testo» è gratuita?
Sì — il testo completo di «Caricamento dei documenti ed estrazione del testo» è 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 Engineering Academy, passa a CoddyKit PRO. Il corso AI Engineering Academy include 4 lezioni in totale.
Cosa imparerò in «Caricamento dei documenti ed estrazione del testo»?
Caricherà PDF, documenti Word e file di testo semplice usando librerie Python, pulirà il testo estratto e lo preparerà per la suddivisione in chunk e l'embedding. Eserciti AI Engineering Academy 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 Engineering Academy?
Non è richiesta alcuna esperienza precedente. AI Engineering Academy 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 «Caricamento dei documenti ed estrazione del testo»?
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 Engineering Academy?
Sì. Ogni lezione AI Engineering Academy 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
- Caricamento dei documenti ed estrazione del testo
- Strategie di chunking: fisso, per frasi e ricorsivo
- Indicizzazione: incorporare e memorizzare i chunk
- Interrogare, recuperare e generare