2010-01-27 2 views
20

파이썬에서 파일의 인코딩을 얻는 방법을 아는 사람이 있습니까? 코덱 모듈을 사용하여 특정 인코딩으로 파일을 열 수는 있지만 미리 알고 있어야합니다.파이썬에서 파일의 인코딩을 아는 법?

import codecs 
f = codecs.open("file.txt", "r", "utf-8") 

파일에 어떤 인코딩이 사용되는지 자동으로 감지하는 방법이 있습니까? 사전에

감사

편집 : 매우 흥미로운 answsers에 대한 감사합니다 모두. 당신은 또한 chardet을 기반으로 http://whatismyencoding.com/에 의해 관심이있을 수 있습니다 (사이트를보다가 병 파이썬 프레임 워크에 의해 제공됩니다)

답변

19

파일 자체를보고 파일 인코딩을 결정하는 '올바른 방법'은 없습니다. 이것은 보편적 인 문제이며 파이썬이나 특정 파일 시스템에 국한되지 않습니다.

XML 파일을 읽는 경우 파일의 첫 번째 줄은 일 수 있으며 인코딩 내용을 알려줍니다.

그렇지 않으면 chardet (다른 답변에서 제공된 해결 방법 중 하나)과 같은 휴리스틱 스 기반 접근 방식을 사용하여 파일의 데이터를 원시 바이트 형식으로 검사하여 인코딩을 추측해야합니다. Windows 사용자 인 경우 Windows API는 파일의 데이터를 기반으로 인코딩을 시도하고 추측 할 수있는 메서드를 제공합니다.

3

chardet을 사용하지만 두 가지 추가 기능이 추가 된 Beautiful Soup에서 Unicode Dammit이 있습니다.

XML 또는 HTML 파일 내부에서 인코딩을 읽으려고합니다. 그런 다음 파일 시작 부분에서 BOM 또는 이와 유사한 것을 찾으려고 시도합니다. 할 수 없다면 chardet을 사용합니다.

3

다음은 인코딩을 추측 할 수있는 작은 스 니펫입니다. 그것은 latin1과 utf8 사이를 꽤 좋은 것으로 추측합니다. 바이트 문자열을 유니 코드 문자열로 변환합니다.

# Attention: Order of encoding_guess_list is import. Example: "latin1" always succeeds. 
encoding_guess_list=['utf8', 'latin1'] 
def try_unicode(string, errors='strict'): 
    if isinstance(string, unicode): 
     return string 
    assert isinstance(string, str), repr(string) 
    for enc in encoding_guess_list: 
     try: 
      return string.decode(enc, errors) 
     except UnicodeError, exc: 
      continue 
    raise UnicodeError('Failed to convert %r' % string) 
def test_try_unicode(): 
    for start, should in [ 
     ('\xfc', u'ü'), 
     ('\xc3\xbc', u'ü'), 
     ('\xbb', u'\xbb'), # postgres/psycopg2 latin1: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 
     ]: 
     result=try_unicode(start, errors='strict') 
     if not result==should: 
      raise Exception(u'Error: start=%r should=%r result=%r' % (
        start, should, result)) 
+0

좋은 아이디어. 감사. –

+0

나는 try-except에서 .decode()를 사용하여 (1) 성공한 변환을 깨거나 (2) encoding_guess_list를 다 써 버린 후 이것을 단순화하고 채택했다. 끝이 실패한 경우 'strict'대신 'replace'로 설정된 오류가있는 다른 .decode()를 적용합니다. – JDM

1
#!/usr/bin/python 

""" 
Line by line detecting encoding if input and then convert it into UTF-8 
Suitable for look at logs with mixed encoding (i.e. from mail systems) 

""" 

import sys 
import chardet 

while 1: 
     l = sys.stdin.readline() 
     e = chardet.detect(l) 

     u = None 
     try: 
       if e['confidence'] > 0.3: 
         u = unicode(l, e['encoding']) 
     except: 
       pass 

     if u: 
       print u, 
     else: 
       print l, 
관련 문제