クライアントからUTF-8の有効文字を受け取ることになっているソケットサーバーがあります。
問題は、一部のクライアント(主にハッカー)がそれを介してすべての間違った種類のデータを送信していることです。
本物のクライアントを簡単に見分けることができますが、後で分析できるように、送信されたすべてのデータをファイルに記録しています。
UnicodeDecodeError
エラーの原因となるこのœ
のような文字が表示されることがあります。
これらの文字の有無にかかわらず、文字列をUTF-8にできるようにする必要があります。
更新:
私の特定のケースでは、ソケットサービスはMTAだったので、以下のようなASCIIコマンドのみを受け取ることを期待しています。
EHLO example.com
MAIL FROM: <[email protected]>
...
これらすべてをJSONに記録しました。
それから善意なしにそこにいる何人かの人々はあらゆる種類のがらくたを売ることにしました。
私の特定のケースでは、ASCII以外の文字を削除してもまったく問題ないのはそのためです。
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:
私がPython 3に移行した今、この種の問題は私のために生じています。Python2が単にSteamがファイルエンコーディングに関する問題を巻き込んでいることを私は知らなかった。
私は違いについてのこの素晴らしい説明と、上記のどれもが私のために働かなかった後に解決策を見つける方法を見つけました。
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
しかし、記事を読んで、すべての解決策に適合するサイズはありません。
エンジンを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')
私にはエラーはありません。
>>> '\x9c'.decode('cp1252')
u'\u0153'
>>> print '\x9c'.decode('cp1252')
œ
私はUnicodeDecodeError
と同じ問題を抱えていました、そして私はこの行でそれを解決しました。最善の方法であるかどうかわからないが、それは私のために働いた。
str = str.decode('unicode_escape').encode('utf-8')
念のために誰かが同じ問題を抱えている。 YouCompleteMe でvimを使用していますが、このエラーメッセージが表示されてycmdを起動できませんでした。export LC_CTYPE="en_US.UTF-8"
、問題は解決しました。
ファイルを変更する必要があるが、ファイルのエンコーディングがわからない場合はどうすればよいですか。エンコーディングがASCII互換であり、ASCIIの部分だけを調べたり変更したい場合は、surrogateescapeエラーハンドラを使ってファイルを開くことができます。
with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
data = f.read()
1つ目は、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']
次に、次の種類のファイルを開きます。
open(current_file, 'r', encoding = get_encoding_type, errors='ignore')