UnicodeDecodeError、無効な継続バイト


257

以下のアイテムが失敗するのはなぜですか?そして、なぜ「latin-1」コーデックで成功するのですか?

o = "a test of \xe9 char" #I want this to remain a string as this is what I am receiving
v = o.decode("utf-8")

結果は:

 Traceback (most recent call last):  
 File "<stdin>", line 1, in <module>  
 File "C:\Python27\lib\encodings\utf_8.py",
 line 16, in decode
     return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError:
 'utf8' codec can't decode byte 0xe9 in position 10: invalid continuation byte

回答:


247

バイナリでは、0xE9はのようになり1110 1001ます。ウィキペディアUTF-8について読むと、そのようなバイトの後に2つの形式が続く必要があることがわかります10xx xxxx。したがって、たとえば:

>>> b'\xe9\x80\x80'.decode('utf-8')
u'\u9000'

しかし、それは例外の機械的な原因にすぎません。この場合、ほぼ確実にラテン1でエンコードされた文字列があります。UTF-8とラテン1の違いがわかります。

>>> u'\xe9'.encode('utf-8')
b'\xc3\xa9'
>>> u'\xe9'.encode('latin-1')
b'\xe9'

(ここでは、Python 2と3の表現を組み合わせて使用​​しています。入力はどのバージョンのPythonでも有効ですが、Pythonインタープリターがこの方法で実際にUnicodeとバイト文字列の両方を表示することはほとんどありません。)


2
おかげで(そして返信した他の人たちにも)、私は255までの文字が直接変換されるという誤った信念の下にありました。
RuiDC、2011

使用時にUnicodeEncodeError: 'ascii' codec can't encode characters in position 2-3: ordinal not in range(128)エラーが発生する.encode(latin-1)
Shiva

234

パンダのread_csvメソッドでcsvファイルを開こうとしたときにも同じエラーが発生しました。

解決策は、エンコーディングを「latin-1」に変更することでした。

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1')

1
これは実際に問題を解決しますか?基本的に、パンダに単純なエンコーディングスタイルにダウングレードしてバイトを無視するように指示しませんか?
Yu Chen

61

UTF-8は無効です。その文字はISO-Latin1のe-acute文字です。そのため、このコードセットで成功します。

文字列を受け取るコードセットがわからない場合は、少し困っています。プロトコル/アプリケーションに単一のコードセット(うまくいけばUTF-8)が選択され、デコードされなかったコードセットを拒否するのが最善です。

それができない場合は、経験則が必要になります。


2
ヒューリスティックについては、chardetライブラリを参照してください。
mlissner 2012年

44

UTF-8はマルチバイトであり、\xe9プラスとそれに続くスペースの組み合わせに対応する文字がないためです。

utf-8とlatin-1の両方で成功する必要があるのはなぜですか?

ここで、同じ文がどのようにutf-8になるかを示します。

>>> o.decode('latin-1').encode("utf-8")
'a test of \xc3\xa9 char'

Latin-1はシングルバイトエンコーディングファミリであるため、そのすべてがUTF-8で定義されている必要があります。しかし、なぜLatin-1が優勝するのでしょうか。
Reihan_amn 2018年

11

開かれたばかりのファイルを操作しているときにこのエラーが発生した場合は、'rb'モードで開いたかどうかを確認してください


2
この回答のおかげで、のエラーを回避することができた UnicodeDecodeError:「をUTF-8」コーデックはできませんデコードバイト0xd7での位置2024079:無効な継続バイト によって soup = BeautifulSoup(open('webpage.html', 'rb'), 'html.parser')
アイザック・フィリップ

6

これは、ヘブライ語を含むテキストを.txtファイルから読んでいるときにも起こりました。

クリックしました: file -> save asこのファイルをUTF-8エンコードとして保存しました


5

通常、utf-8コードエラーは、数値の範囲が0〜127を超える場合に発生します。

この例外を発生させる理由は次のとおりです。

1)コードポイントが128未満の場合、各バイトはコードポイントの値と同じです。2)コードポイントが128以上の場合、Unicode文字列はこのエンコーディングでは表現できません。(この場合、PythonはUnicodeEncodeError例外を発生させます。)

これを克服するために、エンコーディングのセットがあります。最も広く使用されているのは「Latin-1、別名ISO-8859-1」です。

したがって、ISO-8859-1のUnicodeポイント0〜255はLatin-1の値と同じであるため、このエンコーディングに変換するには、コードポイントをバイト値に変換するだけです。255より大きいコードポイントが検出された場合、文字列はLatin-1にエンコードできません。

データセットをロードしようとしたときにこの例外が発生した場合は、この形式を使用してみてください

df=pd.read_csv("top50.csv",encoding='ISO-8859-1')

構文の最後にエンコーディングテクニックを追加します。これにより、データセットのロードが受け入れられます。


こんにちは、SOへようこそ!回答を編集して、この質問にすでに存在する他の回答よりも改善されるようにしてください。
hongsy


-1

この場合、path / file.sqlをアクティブにする.pyを実行しようとしました。

私の解決策は、file.sqlのコードを「BOMなしのUTF-8」に変更することでした。

Notepad ++でそれを行うことができます。

私はコードの一部を残します。

/ コード /

con = psycopg2.connect(host = sys.argv [1]、port = sys.argv [2]、dbname = sys.argv [3]、user = sys.argv [4]、password = sys.argv [5] )

カーソル= con.cursor()sqlfile = open(path、 'r')

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.