UnicodeDecodeError: 'utf8'コーデックはバイト0x9cをデコードできません


289

クライアントからUTF-8の有効な文字を受け取ることになっているソケットサーバーがあります。

問題は、一部のクライアント(主にハッカー)が間違った種類のデータをすべて送信していることです。

私は本物のクライアントを簡単に区別できますが、送信したすべてのデータをファイルに記録しているので、後で分析できます。

このようなエラーœが発生することがありUnicodeDecodeErrorます。

これらの文字の有無にかかわらず、文字列UTF-8を作成できるようにする必要があります。


更新:

私の特定のケースでは、ソケットサービスはMTAだったため、次のようなASCIIコマンドのみを受信することを期待しています。

EHLO example.com
MAIL FROM: <john.doe@example.com>
...

これらすべてをJSONでログに記録していました。

その後、善意のない人々が、あらゆる種類のジャンクを売ることに決めました。

そのため、私の特定のケースでは、非ASCII文字を削除しても問題ありません。


1
文字列はファイルまたはソケットから出ますか?ソケット/ファイルハンドラーを介して送信される前に、文字列のエンコード方法とデコード方法のコード例を投稿していただけませんか?
devsnd 2012

文字列がソケットを経由することを私は書いたか書いていないのですか?ソケットから文字列を読み取り、辞書に入れてからJSONで送信します。これらの文字が原因で、JSON関数が失敗しました。
トランシルブラッド2012

問題のサンプルデータを入力してください
Shubham Sharma

回答:


343

http://docs.python.org/howto/unicode.html#the-unicode-type

str = unicode(str, errors='replace')

または

str = unicode(str, errors='ignore')

注: これにより、問題の文字が取り除かれ(無視され)、文字のない文字列が返されます。

私のアプリケーションでは許可されていない非ASCII入力に対する保護として使用しているので、これは理想的なケースです。

またはcodecsモジュールのopenメソッドを使用してファイルを読み取ります。

import codecs
with codecs.open(file_name, 'r', encoding='utf-8',
                 errors='ignore') as fdata:

45
はい。ただし、キャラクターを失うだけなので、これは通常悪い習慣/危険です。:より良いは、決定または入力文字列のエンコーディングを検出し、例えば、UTF-8のように、最初のエンコードをUnicodeにそれを復号化するstr.decode('cp1252').encode('utf-8')
ベンホイト

場合によっては、そうです、問題を引き起こす可能性があります。私の場合、私のソケットサーバーに接続しているクライアントの不適切なフォーマットとプログラミングに起因する余分な文字のように見えるので、私はそれらを気にしません。
トランシルブラッド2012

文字列の内容が実際に無効である場合、これは実際に役立ちます。私の場合、置換に'\xc0msterdam'変わりますu'\ufffdmsterdam'
PvdL

3
ファイルの読み取りに問題があるためにここまでたどり着いた場合は、ファイルをバイナリモードで開くopen(file_name, "rb")と役立つ場合があります。次に、上記のコメントからベンのアプローチを適用します
kristian

同じオプションがさらに適用されます。たとえば、「something.decode()」
Alexander Stohr

83

エンジンをCからPythonに変更すると、うまくいきました。

エンジンはC:

pd.read_csv(gdp_path, sep='\t', engine='c')

'utf-8'コーデックは位置18のバイト0x92をデコードできません:無効な開始バイト

エンジンはPythonです。

pd.read_csv(gdp_path, sep='\t', engine='python')

エラーはありません。


3
それは実際には良い解決策です。なぜ反対票が投じられたのかわかりません。
'2018

巨大なcsvファイルがある場合、これは良い考えではありません。OutOfMemoryエラーまたはノートブックのカーネルの自動再起動につながる可能性があります。encodingこの場合はを設定する必要があります。
LucasBr

1
すばらしい答えです。ありがとうございました。これでうまくいきました。問題の原因となっているダイヤモンド形の文字の中に「?」がありました。明白な目で、私はインチである「」を持っていました。私は2つのことを理解するためにやった。a)df = pd.read_csv( 'test.csv'、n_rows = 10000)。これはエンジンなしで完全に機能しました。したがって、n_rowsをインクリメントして、どの行にエラーがあったかを特定しました。b)df = pd.read_csv( 'test.csv'、engine = 'python')。これは機能し、df.iloc [36145]を使用してエラー行を印刷しました。これにより、エラーレコードが印刷されました。
Jagannath Banerjee

1
これは私にとっても
うまくいきました...「内部

1
素晴らしい解決策!どうもありがとうございます。
ペチ

62

Python 3に移行したため、この種の問題が発生しました。Python2がファイルエンコーディングの問題を単純に処理するだけだとは思いませんでした。

上記のいずれもうまくいかなかったので、違いと解決策を見つける方法のこの素晴らしい説明を見つけました。

http://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html

つまり、Python 3をPython 2と可能な限り同じように動作させるには、次のコマンドを使用します。

with open(filename, encoding="latin-1") as datafile:
    # work on datafile here

ただし、記事を読んでください。すべてのソリューションに適したサイズはありません。


29
>>> '\x9c'.decode('cp1252')
u'\u0153'
>>> print '\x9c'.decode('cp1252')
œ

16
私は混乱しています、どのようにcp1252を選びましたか?それは私にとってはうまくいきましたが、なぜですか?わからないけど、今は迷子になっています:/。詳しく説明してもらえますか?どうもありがとう !:)
Cyril N.

4
すべてのキャラクターで機能するオプションを提示できますか?より一般的なコードを実装できるように、デコードする必要のある文字を検出する方法はありますか?多くの人がこれを見ていて、私にとっては、一部の破棄は望ましい方法ではないと思います。
トランシルブラッド2013

ご覧のとおり、この質問にはかなりの人気があります。より一般的なソリューションで答えを拡大できると思いますか?
トランシルブラッド2013年

13
「エンコーディングルーレットの推測」に対する一般的な解決策はありません
パピー

5
ウェブ検索、運、直感の組み合わせを使用してそれを見つけた:cp1252 wasused by default in the legacy components of Microsoft Windows in English and some other Western languages
bolov

24

私は同じ問題を抱えていましたがUnicodeDecodeError、この行で解決しました。が最善の方法かどうかはわかりませんが、私にとってはうまくいきました。

str = str.decode('unicode_escape').encode('utf-8')

13

最初に、get_encoding_typeを使用してエンコードのファイルタイプを取得します。

import os    
from chardet import detect

# get file encoding type
def get_encoding_type(file):
    with open(file, 'rb') as f:
        rawdata = f.read()
    return detect(rawdata)['encoding']

2番目は、次のタイプのファイルを開きます。

open(current_file, 'r', encoding = get_encoding_type, errors='ignore')

1
Noneを返すとどうなるか
Chop Labalagun

3

誰かが同じ問題を抱えている場合に備えて。YouCompleteMeでvimを使用していますが、次のエラーメッセージでycmdを開始できませんでしexport LC_CTYPE="en_US.UTF-8"た。問題は解消されました。


2
これはこの質問とどのように関連していますか?
Transilvlad 2014

1
youcompletemeの動作を知っている場合は、まったく同じです。YCMプラグインはソケットアーキテクチャであり、クライアントとサーバー間の通信はソケットを使用しており、どちらもpythonモジュールであり、エンコーディング設定が正しくない場合、パケットをデコードできません
workplaylifecycle

私は同じ問題を抱えています。どこに置くexport LC_CTYPE="en_US.UTF-8"か教えて頂けますか?
Reman、2014年

@Remonnこんにちは、bashのプロファイルファイルがあることをご存知ですか。入れる。
workplaylifecycle 2014年

@hylepo、私はWindowsシステムにいます:)
Reman

3

ファイルに変更を加える必要があるが、ファイルのエンコーディングがわからない場合はどうすればよいですか。エンコーディングがASCII互換であることがわかっていて、ASCII部分のみを調べたり変更したい場合は、surrogateescapeエラーハンドラーでファイルを開くことができます。

with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
    data = f.read()

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