„For line in…” powoduje błąd UnicodeDecodeError: kodek „utf-8” nie może dekodować bajtu

214

Oto mój kod

for line in open('u.item'):
#read each line

za każdym razem, gdy uruchamiam ten kod, pojawia się następujący błąd:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 2892: invalid continuation byte

Próbowałem rozwiązać ten problem i dodać dodatkowy parametr w open (), kod wygląda jak;

for line in open('u.item', encoding='utf-8'):
#read each line

Ale znowu daje ten sam błąd. więc co powinienem zrobić! Proszę pomóż.

SujitS
źródło
3
Zakładam, że źle zakodowane dane.
Andreas Jung
9
Lub po prostu nie dane UTF-8.
Mark Tolonen
Podczas używania Pythona 3 zamiast Pythona 2.7 wystąpił ten błąd. Dla nas sposób działania polegał na pracy z Pythonem 2.7.
Jesse W. Collins,

Odpowiedzi:

403

Jak zasugerował Mark Ransom, znalazłem właściwe kodowanie tego problemu. Kodowanie to „ISO-8859-1”, więc zastąpienie open("u.item", encoding="utf-8")go open('u.item', encoding = "ISO-8859-1")rozwiąże problem.

SujitS
źródło
8
Jawne jest lepsze niż niejawne (PEP 20).
Ioannis Filippidis
6
Sztuka polega na tym, że ISO-8859-1 lub Latin_1 to 8-bitowe zestawy znaków, dlatego wszystkie śmieci mają poprawną wartość. Być może nie do użytku, ale jeśli chcesz zignorować!
Kjeld Flarup
1
Miałem ten sam problem UnicodeDecodeError: kodek „utf-8” nie może zdekodować bajtu 0xd0 na pozycji 32: niepoprawny bajt kontynuacji. Użyłem Pythona 3.6.5, aby zainstalować aws cli. A kiedy próbowałem aws - wersja nie powiodła się z tym błędem. Musiałem więc edytować /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/configparser.py i zmieniłem kod na następujący def read (self, nazwy plików, kodowanie = "ISO-8859-1" ):
Евгений Коптюбенко
3
Czy istnieje automatyczny sposób wykrywania kodowania?
OrangeSherbet
5
@OrangeSherbet Zaimplementowałem wykrywanie za pomocą chardet. Oto jeden-liner (po import chardet) chardet.detect(open(in_file, 'rb').read())['encoding']. Sprawdź tę odpowiedź, aby uzyskać szczegółowe informacje: stackoverflow.com/a/3323810/615422
VertigoRay
51

Pracowałem również dla mnie, ISO 8859-1 dużo zaoszczędzi, hahaha, głównie jeśli użyję interfejsu API rozpoznawania mowy

Przykład:

file = open('../Resources/' + filename, 'r', encoding="ISO-8859-1");
Ryoji Kuwae Neto
źródło
4
Możesz mieć rację, że OP odczytuje ISO 8859-1, jak można wywnioskować z 0xe9 (é) w komunikacie o błędzie, ale powinieneś wyjaśnić, dlaczego twoje rozwiązanie działa. Odniesienie do API rozpoznawania mowy nie pomaga.
RolfBly,
5
O co chodzi z tym średnikiem?
Prawa noga
29

Twój plik tak naprawdę nie zawiera danych zakodowanych w utf-8, zawiera inne kodowanie. Dowiedz się, co to za kodowanie i użyj go w openwywołaniu.

Na przykład w kodowaniu Windows-1252 0xe9będzie to znak é.

Mark Ransom
źródło
4
Jak mogę się dowiedzieć, jakie to kodowanie! Korzystam z systemu Linux
SujitS
4
Nie ma na to sposobu, który zawsze działa, ale zobacz odpowiedź na to pytanie: stackoverflow.com/questions/436220/…
RemcoGerlich
20

Spróbuj to przeczytać przy użyciu pand

pd.read_csv('u.item', sep='|', names=m_cols , encoding='latin-1')
Shashank
źródło
Nie jestem pewien, dlaczego sugerujesz Pandy. Rozwiązaniem jest ustawienie prawidłowego kodowania, na które się tu natknąłeś.
Alastair McCormack
12

Jeśli korzystasz Python 2z następujących rozwiązań:

import io
for line in io.open("u.item", encoding="ISO-8859-1"):
    # do something

Ponieważ encodingparametr nie działa open(), pojawi się następujący błąd:

TypeError: „encoding” jest niepoprawnym argumentem słowa kluczowego dla tej funkcji
Jeril
źródło
1
Ale to jest wersja 3
SujitS
1
Tak, wiem. Pomyślałem, że może to być pomocne dla osób używającychPython 2
Jeril
Pracowałem dla mnie również w Python3
fenkerbb
2
Jeśli chcesz coś łatwiejszego do zapamiętania, 'ISO-8859-1'jest również znany jako 'latin-1'lub 'latin1'.
Max Candocia,
9

Możesz rozwiązać problem za pomocą:

for line in open(your_file_path, 'rb'):

„rb” czyta plik w trybie binarnym. Przeczytaj więcej tutaj . Mam nadzieję, że to pomoże!

Ozcar Nguyen
źródło
6

To działa:

open('filename', encoding='latin-1')

lub:

open('filename',encoding="IS0-8859-1")
Ayesha Siddiqa
źródło
2

Jeśli ktoś ich szuka, jest to przykład konwersji pliku CSV w Pythonie 3:

try:
    inputReader = csv.reader(open(argv[1], encoding='ISO-8859-1'), delimiter=',',quotechar='"')
except IOError:
    pass
użytkownik6832484
źródło
2

Czasami, gdy open(filepath)w filepathrzeczywistości nie ma pliku, pojawia się ten sam błąd, więc najpierw upewnij się, że plik, który próbujesz otworzyć, istnieje:

import os
assert os.path.isfile(filepath)

mam nadzieję, że to pomoże.

xtluo
źródło
1

możesz spróbować w ten sposób:

open('u.item', encoding='utf8', errors='ignore')
FaridLU
źródło
To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienia, zostaw komentarz pod postem. - Z recenzji
MartenCatcher