파이썬 문자열에서 u '\ ufeff'


153

다음과 같은 패턴으로 오류가 발생합니다.

UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128)

확실하지 않은 u'\ufeff'경우 웹 스크래핑시 표시됩니다. 상황을 어떻게 해결할 수 있습니까? .replace()문자열 방법은 작동하지 않습니다.


6
이 입력은 어디에서 오는가? 무엇을하려고합니까? 파이썬 코드를 포함하십시오.

7
덧붙여, 나는 유니 코드 표시를 기억하는 경우 .replace ()가 현대 파이썬에서 작업을 수행 찾을 : s.replace를 (유 '\ ufeff', '')
더그 브래드 쇼

"Modern python"이라고 말할 때 @DougBradshaw는 2.7+ 또는 3.0+를 의미합니까?
teewuane

좋은 지적. 의미는 2.7+입니다.
Doug Bradshaw

답변:


184

유니 코드 문자 U+FEFF는 바이트 순서 표시 또는 BOM이며 빅 엔디안 및 리틀 엔디안 UTF-16 인코딩의 차이점을 나타내는 데 사용됩니다. 올바른 코덱을 사용하여 웹 페이지를 디코딩하면 Python에서 해당 페이지를 제거합니다. 예 :

#!python2
#coding: utf8
u = u'ABC'
e8 = u.encode('utf-8')        # encode without BOM
e8s = u.encode('utf-8-sig')   # encode with BOM
e16 = u.encode('utf-16')      # encode with BOM
e16le = u.encode('utf-16le')  # encode without BOM
e16be = u.encode('utf-16be')  # encode without BOM
print 'utf-8     %r' % e8
print 'utf-8-sig %r' % e8s
print 'utf-16    %r' % e16
print 'utf-16le  %r' % e16le
print 'utf-16be  %r' % e16be
print
print 'utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8')
print 'utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig')
print 'utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16')
print 'utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le')

참고 EF BB BFUTF-8 인코딩 BOM이다. UTF-8에는 필요하지 않지만 서명 (일반적으로 Windows)에서만 사용됩니다.

산출:

utf-8     'ABC'
utf-8-sig '\xef\xbb\xbfABC'
utf-16    '\xff\xfeA\x00B\x00C\x00'    # Adds BOM and encodes using native processor endian-ness.
utf-16le  'A\x00B\x00C\x00'
utf-16be  '\x00A\x00B\x00C'

utf-8  w/ BOM decoded with utf-8     u'\ufeffABC'    # doesn't remove BOM if present.
utf-8  w/ BOM decoded with utf-8-sig u'ABC'          # removes BOM if present.
utf-16 w/ BOM decoded with utf-16    u'ABC'          # *requires* BOM to be present.
utf-16 w/ BOM decoded with utf-16le  u'\ufeffABC'    # doesn't remove BOM if present.

있습니다 utf-16코덱이 필요 BOM이 존재하는, 또는 데이터가 BIG-또는 리틀 엔디안 경우 파이썬은 알 수 없습니다.


201

나는 파이썬 3에서 이것을 만났고이 질문 (및 해결책 )을 발견했다 . 파일을 열 때 Python 3은 인코딩 키워드를 지원하여 인코딩을 자동으로 처리합니다.

이를 사용하지 않으면 BOM이 읽기 결과에 포함됩니다.

>>> f = open('file', mode='r')
>>> f.read()
'\ufefftest'

올바른 인코딩을 제공하면 결과에서 BOM이 생략됩니다.

>>> f = open('file', mode='r', encoding='utf-8-sig')
>>> f.read()
'test'

그냥 내 2 센트.


13
감사합니다. 이것은 실제 솔루션이며 허용되는 답변이어야합니다. 하지만 문자열이 왜 거기에 큰 통찰력은 여기 오는 사람들의 대부분은 간단한 솔루션을 찾고 있으며이 그 것이다.
neurino 2019

3
Excel에서 저장된 CSV 파일을 읽는 CSV DictReader와 동일한 문제가 있습니다.
LArntz

1
예, Excel (Excel에서 생성 된 "csv"조차도)은 정말 엉망입니다.
물수리

4

해당 문자는 BOM 또는 "바이트 주문 표시"입니다. 일반적으로 파일의 처음 몇 바이트로 수신되어 나머지 데이터의 인코딩을 해석하는 방법을 알려줍니다. 캐릭터를 제거하여 계속할 수 있습니다. 오류로 인해 'ascii'로 변환하려고했기 때문에 수행하려는 작업에 대해 다른 인코딩을 선택해야합니다.


4

스크랩하는 내용은 ASCII 텍스트가 아닌 유니 코드로 인코딩되며 ASCII로 변환되지 않는 문자가 표시됩니다. 올바른 '번역'은 원본 웹 페이지가 생각한 바에 따라 다릅니다. 파이썬의 유니 코드 페이지 는 어떻게 작동하는지에 대한 배경을 제공합니다.

결과를 인쇄하거나 파일에 붙이려 고합니까? 이 오류는 문제를 일으키는 데이터를 쓰지 않고 읽지 않는다는 것을 나타냅니다. 이 질문 은 수정 사항을 찾기에 좋은 곳입니다.


0

다음은 Mark Tolonen의 답변을 기반으로합니다. 문자열에는 '|'로 구분 된 단어 'test'의 다른 언어가 포함되어 있으므로 차이점을 확인할 수 있습니다.

u = u'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
e8 = u.encode('utf-8')        # encode without BOM
e8s = u.encode('utf-8-sig')   # encode with BOM
e16 = u.encode('utf-16')      # encode with BOM
e16le = u.encode('utf-16le')  # encode without BOM
e16be = u.encode('utf-16be')  # encode without BOM
print('utf-8     %r' % e8)
print('utf-8-sig %r' % e8s)
print('utf-16    %r' % e16)
print('utf-16le  %r' % e16le)
print('utf-16be  %r' % e16be)
print()
print('utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8'))
print('utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig'))
print('utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16'))
print('utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le'))

테스트 실행은 다음과 같습니다.

>>> u = u'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> e8 = u.encode('utf-8')        # encode without BOM
>>> e8s = u.encode('utf-8-sig')   # encode with BOM
>>> e16 = u.encode('utf-16')      # encode with BOM
>>> e16le = u.encode('utf-16le')  # encode without BOM
>>> e16be = u.encode('utf-16be')  # encode without BOM
>>> print('utf-8     %r' % e8)
utf-8     b'ABCtest\xce\xb2\xe8\xb2\x9d\xe5\xa1\x94\xec\x9c\x84m\xc3\xa1sb\xc3\xaata|test|\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1|\xe6\xb5\x8b\xe8\xaf\x95|\xe6\xb8\xac\xe8\xa9\xa6|\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88|\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe|\xe0\xb4\xaa\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb4\xb6\xe0\xb5\x8b\xe0\xb4\xa7\xe0\xb4\xa8|\xd7\xa4\xd6\xbc\xd7\xa8\xd7\x95\xd7\x91\xd7\x99\xd7\xa8\xd7\x9f|ki\xe1\xbb\x83m tra|\xc3\x96l\xc3\xa7ek|'
>>> print('utf-8-sig %r' % e8s)
utf-8-sig b'\xef\xbb\xbfABCtest\xce\xb2\xe8\xb2\x9d\xe5\xa1\x94\xec\x9c\x84m\xc3\xa1sb\xc3\xaata|test|\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1|\xe6\xb5\x8b\xe8\xaf\x95|\xe6\xb8\xac\xe8\xa9\xa6|\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88|\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe|\xe0\xb4\xaa\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb4\xb6\xe0\xb5\x8b\xe0\xb4\xa7\xe0\xb4\xa8|\xd7\xa4\xd6\xbc\xd7\xa8\xd7\x95\xd7\x91\xd7\x99\xd7\xa8\xd7\x9f|ki\xe1\xbb\x83m tra|\xc3\x96l\xc3\xa7ek|'
>>> print('utf-16    %r' % e16)
utf-16    b"\xff\xfeA\x00B\x00C\x00t\x00e\x00s\x00t\x00\xb2\x03\x9d\x8cTX\x04\xc7m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x00'\x06.\x06*\x06(\x06'\x061\x06|\x00Km\xd5\x8b|\x00,nf\x8a|\x00\xc60\xb90\xc80|\x00*\t0\t@\t\x15\tM\t7\t>\t|\x00*\r0\r?\r6\rK\r'\r(\r|\x00\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x05|\x00k\x00i\x00\xc3\x1em\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|\x00"
>>> print('utf-16le  %r' % e16le)
utf-16le  b"A\x00B\x00C\x00t\x00e\x00s\x00t\x00\xb2\x03\x9d\x8cTX\x04\xc7m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x00'\x06.\x06*\x06(\x06'\x061\x06|\x00Km\xd5\x8b|\x00,nf\x8a|\x00\xc60\xb90\xc80|\x00*\t0\t@\t\x15\tM\t7\t>\t|\x00*\r0\r?\r6\rK\r'\r(\r|\x00\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x05|\x00k\x00i\x00\xc3\x1em\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|\x00"
>>> print('utf-16be  %r' % e16be)
utf-16be  b"\x00A\x00B\x00C\x00t\x00e\x00s\x00t\x03\xb2\x8c\x9dXT\xc7\x04\x00m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x06'\x06.\x06*\x06(\x06'\x061\x00|mK\x8b\xd5\x00|n,\x8af\x00|0\xc60\xb90\xc8\x00|\t*\t0\t@\t\x15\tM\t7\t>\x00|\r*\r0\r?\r6\rK\r'\r(\x00|\x05\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x00|\x00k\x00i\x1e\xc3\x00m\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|"
>>> print()

>>> print('utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8'))
utf-8  w/ BOM decoded with utf-8     '\ufeffABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig'))
utf-8  w/ BOM decoded with utf-8-sig 'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16'))
utf-16 w/ BOM decoded with utf-16    'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le'))
utf-16 w/ BOM decoded with utf-16le  '\ufeffABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'

그것의 가치는 모두 그것을 알고 utf-8-sig하고 utf-16모두 후 원래의 문자열을 돌아 가야 encode하고 decode.


-3

이 문제는 기본적으로 파이썬 코드를 UTF-8 또는 UTF-16 인코딩 으로 저장할 때 발생합니다. 파이썬은 코드 시작 부분에 자동으로 특수 문자를 추가하여 (텍스트 편집기에 표시되지 않음) 인코딩 형식을 식별합니다. 그러나 코드를 실행하려고하면 파이썬 컴파일러가 ASCII 인코딩을 이해 하기 때문에 코드 1의 줄에 구문 오류가 발생 합니다. read () 함수를 사용하여 파일 코드를 볼 때 반환 된 코드 '\ ufeff' 의 시작 부분에 표시됩니다. 이 문제에 대한 가장 간단한 해결책 은 인코딩을 다시 ASCII 인코딩 으로 변경하는 것입니다.(이를 위해 코드를 메모장에 복사하여 저장할 수 있습니다. 기억하십시오! ASCII 인코딩을 선택하십시오 ... 도움이 되길 바랍니다.

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