UnicodeDecodeError : 'utf8'코덱이 바이트 0x9c를 디코딩 할 수 없습니다


289

클라이언트에서 UTF-8 유효한 문자를 수신 해야하는 소켓 서버가 있습니다.

문제는 일부 클라이언트 (주로 해커)가 잘못된 모든 종류의 데이터를 전송한다는 것입니다.

나는 진짜 클라이언트를 쉽게 구별 할 수 있지만, 나중에 분석 할 수 있도록 전송 된 모든 데이터를 파일에 기록하고있다.

때로는 오류 œ를 일으키는 이와 같은 문자 가 UnicodeDecodeError표시됩니다.

해당 문자 유무에 관계없이 문자열 UTF-8을 만들 수 있어야합니다.


최신 정보:

내 특별한 경우 소켓 서비스는 MTA 였으므로 다음과 같은 ASCII 명령 만 수신해야합니다.

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

JSON 으로이 모든 것을 기록하고있었습니다.

그런 다음 좋은 의도가없는 일부 사람들은 모든 종류의 쓰레기를 팔기로 결정했습니다.

그렇기 때문에 특정 경우에는 ASCII가 아닌 문자를 제거하는 것이 좋습니다.


1
문자열이 파일이나 소켓에서 나옵니까? 소켓 / 파일 핸들러를 통해 문자열을 보내기 전에 문자열을 인코딩하고 엔코딩하는 방법에 대한 코드 예제를 게시 할 수 있습니까?
devsnd

문자열이 소켓을 통해 온다는 것을 쓰거나 쓰지 않았습니까? 소켓에서 문자열을 읽고 사전에 넣은 다음 JSON으로 보내십시오. 해당 문자로 인해 JSON 기능이 실패했습니다.
transilvlad

문제의 샘플 데이터를 입력 해 주시겠습니까?
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로 인코딩하는 것이 str.decode('cp1252').encode('utf-8')
좋습니다

어떤 경우에는 그렇습니다. 문제가 생길 수 있습니다. 필자의 경우 소켓 서버에 연결하는 클라이언트의 잘못된 형식 지정 및 프로그래밍에서 비롯된 추가 문자 인 것처럼 보이므로 신경 쓰지 않습니다.
transilvlad

이 사람은 실제로 문자열의 내용이 내 경우에는, 실제로 잘못된 경우 도움 '\xc0msterdam'에 회전 u'\ufffdmsterdam'과 교체
PvdL

3
파일을 읽는 데 문제가있어서 여기에있는 경우 바이너리 모드로 파일을 여는 것이 도움이 될 수 있습니다. open(file_name, "rb")위의 주석에서 Ben의 접근 방식을 적용하십시오
kristian

같은 옵션이 더 많이 적용됩니다. 예 : "something.decode ()"
Alexander Stohr

83

엔진을 C에서 Python으로 변경하면 나에게 속임수가되었습니다.

엔진은 C입니다.

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

'utf-8'코덱은 위치 18에서 바이트 0x92를 디코딩 할 수 없습니다 : 유효하지 않은 시작 바이트

엔진은 파이썬입니다 :

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

나에게 오류가 없습니다.


3
실제로 좋은 해결책입니다. 왜 다운 보트인지 모르겠습니다.
ℕʘʘḆḽḘ

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
훌륭한 솔루션! 정말 고맙습니다.
Pechi

62

파이썬 3으로 옮겼 기 때문에 이런 유형의 문제가 나에게 자랍니다. 파이썬 2가 단순히 파일 인코딩과 관련된 문제를 스팀 롤링한다는 것을 전혀 몰랐습니다.

차이점에 대한이 멋진 설명과 위의 어느 것도 나를 위해 일한 후에 해결책을 찾는 방법을 찾았습니다.

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
모든 캐릭터에 적합한 옵션을 제시해 주시겠습니까? 더 일반적인 코드를 구현할 수 있도록 디코딩해야하는 문자를 감지하는 방법이 있습니까? 나는 많은 사람들이 이것을보고 있고 일부 폐기에 대해 내기처럼 원하는 옵션이 아니라는 것을 내기했다.
transilvlad

보시 다시피이 질문은 꽤 인기가 있습니다. 보다 일반적인 솔루션으로 답변을 확장 할 수 있다고 생각하십니까?
transilvlad

13
"인코딩 룰렛 추측"에 대한 더 일반적인 해결책은 없습니다
Puppy

5
웹 검색, 행운과 직감의 조합을 사용하여 발견 : cp1252used by default in the legacy components of Microsoft Windows in English and some other Western languages
bolov 21시 58 분

24

나는 같은 문제가 UnicodeDecodeError있었고이 줄로 해결했다. 최선의 방법인지 모르겠지만 그것은 나를 위해 일했습니다.

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

13

첫 번째는 get_encoding_type을 사용하여 파일 형식의 encode를 가져옵니다.

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

1
None을 반환하면 어떻게됩니까
Chop Labalagun

3

누군가 같은 문제가있는 경우. vim을 YouCompleteMe 와 함께 사용하고 있는데이 오류 메시지와 함께 ycmd를 시작하지 못했습니다 export LC_CTYPE="en_US.UTF-8". 문제는 사라졌습니다.


2
이것이이 질문과 어떤 관련이 있습니까?
transilvlad

1
당신이 당신을 완료하는 방법을 알고 있다면 정확히 동일합니다. Ycm 플러그인은 소켓 아키텍처이며, 클라이언트와 서버 간의 통신은 소켓을 사용하고 있으며, 둘 다 파이썬 모듈이며 인코딩 설정이 올바르지 않으면 패킷을 디코딩 할 수 없습니다
workplaylifecycle

나도 같은 문제가있어. 어디에 두어야하는지 말씀해 주 export LC_CTYPE="en_US.UTF-8"시겠습니까?
Reman

@Remonn 안녕하세요, 우리는 bash에 대한 프로필 파일이 있다는 것을 알고 있습니까? 안에 넣다.
workplaylifecycle 2016 년

@hylepo, 저는 Windows 시스템에 있습니다 :)
Reman

3

파일을 변경해야하지만 파일의 인코딩을 모르는 경우 어떻게해야합니까? 인코딩이 ASCII와 호환되고 ASCII 부분 만 검사하거나 수정하려는 경우 surrogateescape 오류 처리기를 사용하여 파일을 열 수 있습니다.

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

0

나는이 문제를 추가하여 해결했습니다.

df = pd.read_csv(fileName,encoding='latin1')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.