codememo

UnicodeError: 'charmap' 코덱을 인코딩할 수 없음 - 에 대한 문자 맵, 인쇄 함수

tipmemo 2023. 6. 27. 22:15
반응형

UnicodeError: 'charmap' 코덱을 인코딩할 수 없음 - 에 대한 문자 맵, 인쇄 함수

POST 방식으로 웹페이지에 데이터를 전송하기 위해 파이썬(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()는 메드a를니다반을 합니다.bytesUTF-8 (UTF-8) IDLE 하지 않고 .Windows용 IDLE GUI를 사용하지 않고 대신 Windows 콘솔을 사용하기 전까지는 괜찮을 것 같았습니다.반환된 페이지에는 인쇄 기능이 Windows GUI(코드 페이지 1252)에서는 잘 번역되지만 Windows 콘솔(코드 페이지 850)에서는 잘 번역되지 않는 U+2014 문자(em-dash)가 있습니다. 때려가 ,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가 질문방 대신 하이픈으로 번역하면 더 좋을 것 같습니다.

문제는 emdash가 아니라(특히 그 문제를 해결하기 위한 몇 가지 방법을 생각할 수 있습니다) 강력한 코드를 작성해야 합니다.나는 데이터베이스의 데이터를 페이지에 제공하고 있으며 그 데이터는 돌아올 수 있습니다.다른 많은 충돌 사례를 예상할 수 있습니다. 'A' U+00c1(내 데이터베이스에서 가능)은 CP-850(서유럽 언어의 경우 DOS/Windows 콘솔 인코딩)으로 변환될 수 있지만 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 Wrapper" 섹션이 흥미롭습니다.기본적으로 I/O 인코딩 기능을 다음과 같이 변경하도록 되어 있습니다.

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

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

    CGI에서 HTML을 출력하는 데 사용되는 경우 'strict'를 'xmlcharreplace'로 대체하여 인쇄 불가능한 문자에 대한 HTML 인코딩 태그를 가져올 수 있습니다.

    다른 인코딩을 설정하여 접근 방식을 자유롭게 수정할 수 있습니다.지정되지 않은 데이터를 출력해도 작동하지 않습니다.따라서 모든 데이터, 입력, 텍스트를 유니코드로 올바르게 변환할 수 있어야 합니다.

    # -*- 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
    

Dirk Stöcker의 답변을 바탕으로 Python 3의 인쇄 기능을 위한 깔끔한 래퍼 기능이 있습니다.인쇄물을 사용하는 것처럼 사용합니다.

추가적으로, 마지막 디코드 단계로 인해 다른 답변과 비교하여 텍스트가 바이테어레이('b'콘텐츠')로 인쇄되지 않고 일반 문자열('콘텐츠')로 인쇄됩니다.

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

디버깅을 위해 다음을 사용할 수 있습니다.print(repr(data)).

텍스트를 표시하려면 항상 유니코드를 인쇄합니다.스크립트 내에서 Cp850과 같은 환경의 문자 인코딩을 하드 코딩하지 마십시오.HTTP 응답을 디코딩하려면 Python에서 HTTP 응답의 문자 집합/인코딩을 가져오는 좋은 방법을 참조하십시오.

유니코드를 Windows 콘솔로 인쇄하려면 패키지를 사용할 수 있습니다.

저는 이것을 더 깊이 파고들었고 최고의 해결책이 여기에 있다는 것을 발견했습니다.

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

제 경우 "UnicodeEncodeError: 'charmap' 코덱은 문자를 인코딩할 수 없습니다.

원래 코드:

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

새 코드:

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

Windows 명령줄을 사용하여 데이터를 인쇄하는 경우

chcp 65001

나한테 효과가 있었어요!

Python 3.6(아마도 3.5 이상)을 사용하면 더 이상 해당 오류가 발생하지 않습니다.v3.4를 사용하고 있어서 비슷한 문제가 있었는데 제거하고 다시 설치한 후에 문제가 사라졌습니다.

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

반응형