[python] UnicodeDecodeError : ‘ascii’코덱은 위치 2에서 0xd1 바이트를 디코딩 할 수 없습니다. 서 수가 범위에 없습니다 (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])

API로 보내야하기 때문에 lat 및 lng를 제외한 모든 것을 인코딩하고 있습니다. 프로그램을 실행하여 데이터 세트를 내가 사용할 수있는 것으로 구문 분석하면 다음과 같은 Traceback이 표시됩니다.

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에서 앱 빌드의 일부라고 말해야한다고 생각합니다. 이 주제에 대한 여러 게시물을 읽었지만 직접 적용되는 게시물은 없습니다. 어떤 도움이라도 대단히 감사하겠습니다.

문제를 일으키는 일부 비표준 문자가 Ñ이고 가능하면 É인지 알고 싶을 수도 있습니다.



답변

유니 코드는 UTF-8과 같지 않습니다. 후자는 전자의 인코딩 일뿐 입니다.

당신은 그것을 잘못된 방식으로하고 있습니다. 당신은된다 읽는 UTF-8 인코딩 이 필요하므로, 데이터를 디코딩 유니 코드 문자열로 UTF-8 인코딩 된 문자열.

그러니 그냥 교체 .encode와 함께 .decode, 그것이 작동해야합니다 (.CSV 인 경우 UTF-8 인코딩).

하지만 부끄러워 할 것은 없습니다. 프로그래머 5 명 중 3 명은 처음에는 이것을 이해하는 데 어려움을 겪었습니다.

업데이트 : 입력 데이터가 UTF-8로 인코딩 되지 않은.decode() 경우에는 물론 적절한 인코딩 을 사용해야합니다 . 아무것도 주어지지 않으면 python은 ASCII가 아닌 문자에서 분명히 실패하는 ASCII를 가정합니다.


답변

다음 줄을 코드에 추가하십시오.

import sys
reload(sys)
sys.setdefaultencoding('utf-8')


답변

Python 3 사용자 용. 넌 할 수있어

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

그것은 플라스크에서도 작동합니다 🙂


답변

오류의 주된 이유는 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')

이런 식으로 파이썬은 ASCII 범위를 벗어나는 문자열 내의 문자를 예상 할 수 있습니다.

단, 파이썬 버전 3.5 이상을 사용하는 경우 reload () 함수를 사용할 수 없으므로 디코드를 사용하여 수정해야합니다.

name = school_name.decode('utf8').encode('utf8')


답변

Python 3 사용자의 경우 :

인코딩을 ‘ascii’에서 ‘latin1’로 변경하면 작동합니다.

또한 아래 스 니펫을 사용하여 상위 10000 바이트를 읽어 인코딩을 자동으로 찾을 수 있습니다.

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


답변

내 컴퓨터에 잘못된 로케일이 설정되어 있습니다.

내가 먼저 했어

>>> import locale
>>> locale.getpreferredencoding(False)
'ANSI_X3.4-1968'

locale.getpreferredencoding(False)open()인코딩을 제공하지 않을 때 호출되는 함수 입니다. 출력은이어야 'UTF-8'하지만이 경우에는 ASCII 변형입니다 .

그런 다음 bash 명령을 실행 locale하고이 출력을 얻었습니다.

$ locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

그래서 파이썬이 UTF-8 대신 ASCII로 파일을 열도록하는 기본 Ubuntu 로케일을 사용하고있었습니다. 로케일 을 다음 으로 설정 해야했습니다.en_US.UTF-8

sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo dpkg-reconfigure locales

로케일 시스템 전체를 변경할 수없는 경우 다음과 같이 모든 Python 코드를 호출 할 수 있습니다.

PYTHONIOENCODING="UTF-8" python3 ./path/to/your/script.py

또는

export PYTHONIOENCODING="UTF-8"

실행하는 셸에서 설정합니다.


답변

인증서를 생성하거나 갱신하는 동안 certbot을 실행하는 동안이 문제가 발생하면 다음 방법을 사용하십시오.

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

이 명령은 주석의 한 .conf 파일에서 문제가되는 문자 “´”를 찾았습니다. 그것을 제거하고 (원하는대로 주석을 편집 할 수 있음) nginx를 다시로드하면 모든 것이 다시 작동했습니다.

출처 : https://github.com/certbot/certbot/issues/5236