IT

UnicodeEncodeError : 'charmap'코덱이 인코딩 할 수 없습니다-

lottoking 2020. 6. 14. 10:06
반응형

UnicodeEncodeError : 'charmap'코덱이 인코딩 할 수 없습니다- , 인쇄 기능 [중복]


이 질문에는 이미 답변이 있습니다.

POST 메서드를 사용하여 일부 데이터를 웹 페이지로 보내는 Python (Python 3.3) 프로그램을 작성 중입니다. 주로 디버깅 프로세스의 경우 페이지 결과를 가져 와서 print()기능을 사용하여 화면에 표시합니다 .

코드는 다음과 같습니다

conn.request("POST", resource, params, headers)
response = conn.getresponse()
print(response.status, response.reason)
data = response.read()
print(data.decode('utf-8'));

HTTPResponse .read()메소드는 bytes페이지를 인코딩 하는 요소 (잘 포맷 된 UTF-8 문서)를 반환합니다 .Windows 용 IDLE GUI 사용을 중단하고 Windows 콘솔을 대신 사용할 때까지 괜찮 았습니다. 반환 된 페이지에는 U + 2014 문자 (em-dash)가 있으며 인쇄 기능은 Windows GUI (코드 페이지 1252)에서 잘 번역되지만 Windows 콘솔 (코드 페이지 850)에서는 잘 번역되지 않습니다. strict기본 동작이 주어지면 다음과 같은 오류가 발생합니다.

UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 10248: character maps to <undefined>

이 추악한 코드를 사용하여 문제를 해결할 수 있습니다.

print(data.decode('utf-8').encode('cp850','replace').decode('cp850'))

이제 문제가되는 문자 "—"를로 바꿉니다 ?. 이상적인 경우는 아니지만 (하이픈이 더 나은 대체물이어야 함) 내 목적에 충분합니다.

내 솔루션에서 싫어하는 몇 가지가 있습니다.

  1. 이 코드는 모든 디코딩, 인코딩 및 디코딩으로 추악합니다.
  2. 이 경우에만 문제를 해결합니다. 다른 인코딩 (latin-1, cp437, cp1252 등)을 사용하여 시스템 용 프로그램을 이식하면 대상 인코딩을 인식해야합니다. 그렇지 않습니다. (예를 들어, IDLE GUI를 다시 사용하면 이전에는 발생하지 않았던 emdash도 손실됩니다)
  3. emdash가 심문 뱅 대신 하이픈으로 변환되면 더 좋을 것입니다.

문제는 난처하지는 않지만 (특히 문제를 해결하는 여러 가지 방법을 생각할 수 있음) 강력한 코드를 작성해야합니다. 데이터베이스의 데이터를 페이지에 공급하면 해당 데이터가 다시 올 수 있습니다. 다른 많은 충돌 사례를 예상 할 수 있습니다. 'Á'U + 00c1 (데이터베이스에서 가능)은 CP-850 (서유럽 언어의 경우 DOS / Windows Console encodign)으로 변환 할 수 있지만 CP-437 (미국의 경우 인코딩)으로 변환 할 수는 없습니다. 영어 (많은 Windows 설치에서 기본값 임).

따라서 질문 :

출력 인터페이스 인코딩에서 코드를 무시할 수있는 더 좋은 솔루션이 있습니까?


이에 대한 세 가지 해결책이 있습니다.

  1. 출력 인코딩을 변경하면 항상 UTF-8이 출력됩니다. 예를 들어 Python 에서 stdout을 파이핑 할 때 올바른 인코딩 설정을 참조하십시오 . 그러나이 예제를 작동시키지 못했습니다.

  2. 다음 예제 코드는 출력에 대상 문자 세트를 인식시킵니다.

    # -*- coding: utf-8 -*-
    import sys
    
    print sys.stdout.encoding
    print u"Stöcker".encode(sys.stdout.encoding, errors='replace')
    print u"Стоескер".encode(sys.stdout.encoding, errors='replace')
    

    이 예는 내 이름에 인쇄 할 수없는 문자를 물음표로 바꿉니다.

    myprint출력을 올바르게 인코딩하기 위해 해당 메커니즘을 사용하여 사용자 정의 인쇄 기능 (예 myprint:)을 생성하면 전체 코드를보기 흉하게 보이게하지 않고도 인쇄를 필요한 위치로 간단히 교체 할 수 있습니다 .

  3. 소프트웨어 시작시 출력 인코딩을 전체적으로 재설정하십시오.

    http://www.macfreek.nl/memory/Encoding_of_Python_stdout 페이지 에는 출력 인코딩을 변경하는 방법에 대한 요약이 있습니다. 특히 "Stdout 주변의 StreamWriter 래퍼"섹션이 흥미 롭습니다. 본질적으로 다음과 같이 I / O 인코딩 기능을 변경한다고 말합니다.

    파이썬 2에서 :

    if sys.stdout.encoding != 'cp850':
      sys.stdout = codecs.getwriter('cp850')(sys.stdout, 'strict')
    if sys.stderr.encoding != 'cp850':
      sys.stderr = codecs.getwriter('cp850')(sys.stderr, 'strict')
    

    파이썬 3에서 :

    if sys.stdout.encoding != 'cp850':
      sys.stdout = codecs.getwriter('cp850')(sys.stdout.buffer, 'strict')
    if sys.stderr.encoding != 'cp850':
      sys.stderr = codecs.getwriter('cp850')(sys.stderr.buffer, 'strict')
    

    If used in CGI outputting HTML you can replace 'strict' by 'xmlcharrefreplace' to get HTML encoded tags for non-printable characters.

    Feel free to modify the approaches, setting different encodings, .... Note that it still wont work to output non-specified data. So any data, input, texts must be correctly convertable into unicode:

    # -*- coding: utf-8 -*-
    import sys
    import codecs
    sys.stdout = codecs.getwriter("iso-8859-1")(sys.stdout, 'xmlcharrefreplace')
    print u"Stöcker"                # works
    print "Stöcker".decode("utf-8") # works
    print "Stöcker"                 # fails
    

Based on Dirk Stöcker's answer, here's a neat wrapper function for Python 3's print function. Use it just like you would use print.

As an added bonus, compared to the other answers, this won't print your text as a bytearray ('b"content"'), but as normal strings ('content'), because of the last decode step.

def uprint(*objects, sep=' ', end='\n', file=sys.stdout):
    enc = file.encoding
    if enc == 'UTF-8':
        print(*objects, sep=sep, end=end, file=file)
    else:
        f = lambda obj: str(obj).encode(enc, errors='backslashreplace').decode(enc)
        print(*map(f, objects), sep=sep, end=end, file=file)

uprint('foo')
uprint(u'Antonín Dvořák')
uprint('foo', 'bar', u'Antonín Dvořák')

For debugging purposes, you could use print(repr(data)).

To display text, always print Unicode. Don't hardcode the character encoding of your environment such as cp850 inside your script. To decode the http response, see A good way to get the charset/encoding of an HTTP response in Python.

To print Unicode to Windows console, you could use win-unicode-console package.


I dug deeper into this and found the best solutions are here.

http://blog.notdot.net/2010/07/Getting-unicode-right-in-Python

In my case I solved "UnicodeEncodeError: 'charmap' codec can't encode character "

original code:

print("Process lines, file_name command_line %s\n"% command_line))

New code:

print("Process lines, file_name command_line %s\n"% command_line.encode('utf-8'))  

If you are using Windows command line to print the data, you should use

chcp 65001

This worked for me!


If you use Python 3.6 (possibly 3.5 or later), it doesn't give that error to me anymore. I had a similar issue, because I was using v3.4, but it went away after I uninstalled and reinstalled.

참고URL : https://stackoverflow.com/questions/14630288/unicodeencodeerror-charmap-codec-cant-encode-character-maps-to-undefined

반응형