programing

UnicodeDecodeError: 'ascii' 코덱이 위치 2에서 바이트 0xd1을 디코딩할 수 없음: 순서가 범위에 없음(128)

telebox 2023. 9. 24. 12:45
반응형

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])

lat와 lng를 제외한 모든 것을 API로 보내야 하기 때문에 인코딩합니다.내가 사용할 수 있는 데이터셋을 파싱하기 위해 프로그램을 실행하면 다음과 같은 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가 UTF-8 ).입니다(.csv UTF-8 ).

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

업데이트: 입력 데이터가 UTF-8 인코딩이 되어 있지 않다면 다음 작업을 수행해야 합니다..decode()물론 적절한 부호화를 통해서 말입니다.아무것도 주어지지 않으면 python은 ASCII를 가정하는데, ASCII가 아닌 문자에서는 당연히 실패합니다.

코드에 다음 행을 추가하면 됩니다.

1.피톤2

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

2.피톤3

import sys
from importlib import reload
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')

이 방법으로 python은 문자열 내에서 ASCII 범위를 벗어나는 문자를 예측할 수 있습니다.

그러나 python 버전 3.5 이상을 사용하는 경우 reload() 기능을 사용할 수 없으므로 decode 등을 사용하여 수정해야 합니다.

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

명령으로 사용할 로케일을 확인합니다.아니면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

또는 Python 코드를 실행하기 전에 이 명령을 실행합니다.

export PYTHONIOENCODING="UTF-8"

당신이 그 안에 있는 포탄 안에 그것을 넣는 겁니다.


제 경우에는 제가 사용하고 있었습니다.POSIX Ubuntu 일 대신 일:en_US.UTF-8, 그래서 저는 이 결과를 보았습니다.

$ 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로 파일을 열게 되었습니다.

Python이 어떤 로케일을 사용하고 있는지 다음과 같이 확인할 수 있습니다.

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

locale.getpreferredencoding(False) 는 인코딩을 제공하지 않을 때 호출되는 함수입니다.출력은 다음과 같아야 합니다.'UTF-8', 하지만 저 같은 경우엔 그랬습니다.'ANSI_X3.4-1968', ASCII의 일부 변형입니다.

Python 3 사용자의 경우:

인코딩을 'ascii'에서 'latin1'로 변경하면 됩니다.

또한 아래 토막글을 사용하여 상위 10000 바이트를 읽음으로써 인코딩을 자동으로 찾을 수 있습니다.

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

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

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

이 명령은 주석의 .conf 파일 중 하나에서 불쾌감을 주는 문자 "´"을 찾았습니다.제거 후(댓글을 원하는 대로 편집할 수 있음) nginx를 다시 로드하면 모든 것이 다시 작동했습니다.

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

또는 유니코드 텍스트인 경우 Python에서 텍스트를 다룰 때는 유니코드라는 것을 적어 둡니다.

text=u'unicode text' 대신에 ttext='unicode text'.

이건 내 경우에 효과가 있었어요

도커 컨테이너 내부에서 이 문제를 다루고 있습니다.로케일만 생성하고 더 이상의 작업은 수행하지 않으면 됩니다.

sudo locale-gen en_US en_US.UTF-8

로케일이 이미 설치되고 구성되어 있었기 때문에 저는 그것으로 충분했습니다.로케일을 설치하고 구성해야 하는 경우 도커 파일에 다음 부분을 추가합니다.

RUN apt update && apt install locales && \
    sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=en_US.UTF-8

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL en_US.UTF-8

다음과 같이 테스트했습니다.

cat <<EOF > /tmp/test.txt
++*=|@#|¼üöäàéàè!´]]¬|¢|¢¬|{ł|¼½{}}
EOF

python3
import pathlib; pathlib.Path("/tmp/test.txt").read_text()

lat and long 때문에 UTF 16을 인코딩하여 오픈합니다.

with open(csv_name_here, 'r', encoding="utf-16") as f:

'r' 읽기 대신 'rb' 읽기 이진 변수만 사용하면 작동합니다.

Pickle을 사용하여 언로딩을 진행하던 중 이 문제가 발생하였습니다. 시도해 보십시오.

data = pickle.load(f,encoding='latin1')

언급URL : https://stackoverflow.com/questions/10406135/unicodedecodeerror-ascii-codec-cant-decode-byte-0xd1-in-position-2-ordinal

반응형