Errore 'UnicodeDecodeError' aprendo file in Python, aiutami?

👤 Iniziato da @lazzaropiras9
📅 01/07/2025 13:41
📁 Programmazione 🌐 IT
Avatar di lazzaropiras9
Ciao a tutti, sto lavorando a un progetto personale per digitalizzare vecchi archivi di testo e mi imbatto sempre in questo errore. Quando apro certi file .txt, soprattutto quelli più datati, Python lancia un 'UnicodeDecodeError: 'utf-8' codec can't decode byte...'. Ho provato a specificare encoding='latin-1' o 'iso-8859-1', ma alcuni caratteri restano ancora illeggibili. Questo è un frammento del codice che uso:

with open('vecchio_file.txt', 'r', encoding='utf-8') as f:
contenuto = f.read()

Qualcuno ha esperienza con file di testo obsoleti? Esiste un modo per rilevare l'encoding automaticamente senza perdere dati? Oppure strumenti specifici per questi casi? Ogni suggerimento è benvenuto, grazie mille!
Avatar di gualtierorusso99
Ecco, il classico incubo degli encoding! Ti capisco benissimo, lavorare con file storici è come aprire scatole di cioccolatini: non sai mai che schifezza ti trovi dentro. Prova così:

1. **chardet è tuo amico** - Installa `pip install chardet` e usa:
```python
import chardet
with open('vecchio_file.txt', 'rb') as f:
rawdata = f.read()
result = chardet.detect(rawdata)
encoding = result['encoding']
```
Attenzione: non è infallibile, ma per testi italiani spesso azzecca cp1252 o iso-8859-15.

2. **Prova la bomba a mano:**
```python
with open('vecchio_file.txt', 'r', encoding='cp1252', errors='replace') as f:
```
Sostituisce i caratteri illeggibili con (meglio che crashare). Se vuoi tenerli provi `errors='ignore'`, ma perdi dati.

3. **Un'opzione nucleare:**
```python
encodings = ['utf-8', 'latin-1', 'cp1252', 'iso-8859-15', 'mac_roman']
for enc in encodings:
try:
with open('vecchio_file.txt', 'r', encoding=enc) as f:
contenuto = f.read()
break
except UnicodeDecodeError:
pass
```

Per i file più ostici, prova **iconv** da terminale (`iconv -f ORIGINALE -t UTF-8 input.txt > output.txt`). E se tutto fallisce, preparati al debug manuale esaminando i byte offensivi con `hexdump -C`. In bocca al lupo!
Avatar di porziamorelli6
Ciao @lazzaropiras9, che bel rompicapo! Con i file storici italiani è una lotta continua, ti capisco. @gualtierorusso99 ha dato ottimi spunti, ma aggiungo due cose che mi hanno salvato in progetti simili:

1. **`charset-normalizer` è più preciso di `chardet`** per testi brevi o misti. Prova:
```python
from charset_normalizer import from_bytes
with open('vecchio_file.txt', 'rb') as f:
result = from_bytes(f.read()).best()
print(result.encoding)
```

2. **Gli errori "ostinati" spesso vengono da:**
- Caratteri **CP437** (vecchi DOS italiani, soprattutto se vedi lettere accentate come Å o Æ)
- Encoding **Windows-1250** per testi dell'Europa centrale con influenze slave
- **ISO-8859-15** (quello con l’euro €) che molti confondono con latin-1

3. Se tutto fallisce, usa **`ftfy`**:
```python
import ftfy
contenuto = ftfy.fix_text(contenuto_rotto)
```
Ricostruisce gli errori "a mano" combinando logica e statistica, fenomenale per i file maltrattati.

Bonus: **Mai usare `errors='ignore'`**! Meglio `errors='backslashreplace'` per identificare i byte corrotti e poi fare un cleaning mirato. Tienici aggiornati!
Avatar di marisariva1
Ciao @lazzaropiras9, che bella sfida! Anch'io ho sbattuto la testa su questi problemi con archivi storici. Provando a sintetizzare:

1. **charset-normalizer** è la svolta:
```python
from charset_normalizer import from_bytes
with open('vecchio_file.txt', 'rb') as f:
risultato = from_bytes(f.read()).best()
encoding_detect = risultato.encoding or 'cp1252' # fallback sicuro per l'italiano
```
Usalo prima di aprire il file - spesso becca encoding ibridi che chardet ignora.

2. **Se trovi ancora geroglifici:**
- Prova `MacRoman` per testi anni '90 da sistemi Apple
- **Fai un print dei primi 100 caratteri** con vari encoding: ho risolto una volta riconoscendo un cp437 da DOS italiano (quelle Å erano à!)

3. **Salvataggio sostenibile:**
```python
with open(file, 'r', encoding=encoding_detect, errors='replace') as f:
contenuto = f.read()
with open('nuovo_file.txt', 'w', encoding='utf-8') as f_out: # migra a UTF-8
f_out.write(contenuto)
```
Così archivi in modo futuro-proof evitando nuovi errori.

Se hai un campione d'errore, incollalo qui: a volte i caratteri strani rivelano subito l'encoding!
Avatar di lazzaropiras9
Ciao @marisariva1, grazie infinite per questi consigli preziosi! Il tuo approccio con `charset-normalizer` è una rivelazione - non sapevo gestisse meglio gli ibridi rispetto a chardet. Proverò subito, specie quel fallback a `cp1252` per i testi italiani.

La storia del `cp437` da DOS mi ha fatto sorridere: domani scandaglierò i primi caratteri dei file più ostici cercando quelle Å misteriose! Se trovo altri geroglifici, posterò un campione qui. Nel frattempo, applicherò il tuo metodo di migrazione in UTF-8: è un'ottima strategia per preservare questi archivi senza impazzire.
Avatar di nikevitale74
@lazzaropiras9 La tua passione per questi archivi mi intriga! Quel mix tra detective work e archeologia digitale è affascinante. Ho vissuto lo stesso incubo con file anni '80 e ti confermo: `charset-normalizer` è un salvagente, soprattutto quando becca quelle contaminazioni bizzarre tra CP437 e latin-1 che sembrano fatte apposta per mandarti in tilt.

Se incappi in altri geroglifici, prova a dare un'occhiata anche alle sequenze di escape: una volta mi sono ritrovato con un file che mescolava ASCII art e codepage polacco - uno spettacolo surreale. L'opzione `errors='surrogateescape'` a volte aiuta a tenere in piedi il ponte mentre migri a UTF-8.

E quando tutto fallisce... c'è sempre la scorciatoia del caffè doppio e della pazienza zen. Keep us posted!

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!