web-dev-qa-db-ja.com

UnicodeDecodeError: 'ascii'コーデックは位置2のバイト0xd1をデコードできません:ordinal not in range(128)

いくつかの非標準文字を含む非常に大きなデータセットを使用しようとしています。ジョブの仕様に従ってユニコードを使用する必要がありますが、困惑しています。 (そして、おそらくそれをすべて間違っている。)

次を使用してCSVを開きます。

 15     ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"')

次に、私はそれをエンコードしようとします:

name=school_name.encode('utf-8'), street=row[9].encode('utf-8'), city=row[10].encode('utf-8'), state=row[11].encode('utf-8'), Zip5=row[12], Zip4=row[13],county=row[25].encode('utf-8'), lat=row[22], lng=row[23])

Latとlngを除くすべてをエンコードしています。これらはAPIに送信する必要があるためです。プログラムを実行して、使用可能なデータセットを解析すると、次のトレースバックが取得されます。

Traceback (most recent call last):
  File "Push_into_db.py", line 80, in <module>
    main()
  File "Push_into_db.py", line 74, in main
    district_map = buildDistrictSchoolMap()
  File "Push_into_db.py", line 32, in buildDistrictSchoolMap
    county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)

python 2.7.2を使用していることを伝えておく必要があると思いますが、これはDjango 1.4でビルドされたアプリの一部です。私はこのトピックに関するいくつかの投稿を読みましたが、それらのどれも直接適用されないようです。どんな助けも大歓迎です。

また、問題の原因となっている非標準文字の一部がÑであり、おそらくÉであることを知りたい場合があります。

91
jelkimantis

UnicodeはUTF-8とは異なります。後者は、前者のエンコードにすぎません。

あなたはそれを間違った方法でやっています。 読み取り UTF-8 -エンコードデータであるため、デコード UTF-8エンコードされた文字列をUnicode文字列に変換する必要があります。

したがって、.encode.decodeに置き換えるだけで機能します(.csvがUTF-8エンコードされている場合)。

恥ずかしいことはありませんが。 5人に3人のプログラマーは、これを最初に理解するのに苦労したに違いないと思います;)

更新:入力データがnot UTF-8でエンコードされている場合、もちろん適切なエンコードで.decode()する必要があります。何も指定しない場合、pythonはASCIIを想定しますが、これは明らかに非ASCII文字では失敗します。

136
ch3ka

この行をコードに追加するだけです:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
74
khelili miliana

Python 3ユーザーの場合。できるよ

with open(csv_name_here, 'r', encoding="utf-8") as f:
    #some codes

flaskでも動作します:)

15
screaminghard

このエラーの主な理由は、pythonが想定するデフォルトのエンコードがASCIIであることです。したがって、encode('utf8')でエンコードされる文字列データにASCII範囲外の文字が含まれている場合、 'hgvcj터파크387'などの文字列の場合、pythonは、文字列が予期されたエンコード形式ではないためエラーをスローします。

バージョン3.5より前のpythonバージョンを使用している場合、信頼できる修正方法は、pythonが想定するデフォルトのエンコードをutf8に設定することです。

import sys
reload(sys)
sys.setdefaultencoding('utf8')
name = school_name.encode('utf8')

このようにすると、pythonは、ASCIIの範囲外の文字列内の文字を予測できます。

ただし、pythonバージョン3.5以降を使用している場合、reload()関数は使用できないため、decodeなどを使用して修正する必要があります。

name = school_name.decode('utf8').encode('utf8')
8
Temi Fakunle

証明書の作成または更新中にcertbotを実行中にこの問題が発生した場合は、次の方法を使用してください

grep -r -P '[^\x00-\x7f]' /etc/Apache2 /etc/letsencrypt /etc/nginx

このコマンドは、コメント内の1つの.confファイルで問題の文字「 ´」を検出しました。それを削除して(コメントは自由に編集できます)、nginxをリロードすると、すべてが再び機能しました。

ソース: https://github.com/certbot/certbot/issues/5236

1
Anish Varghese

Python 3ユーザーの場合:

エンコーディングを「ascii」から「latin1」に変更すると機能します。

また、以下のスニペットを使用して上位10000バイトを読み取ることにより、エンコードを自動的に見つけてみることができます。

import chardet  
with open("dataset_path", 'rb') as rawdata:  
            result = chardet.detect(rawdata.read(10000))  
print(result)
1
Prithvi

緯度と経度のため、UTF 16エンコーディングで開きます。 open(csv_name_here、 'r'、encoding = "utf-16")でfとして:

0
karthik r