如何知道Python中文件的编码?

时间:2010-01-27 05:46:09

标签: python encoding character-encoding

有人知道如何在Python中获取文件的编码。我知道您可以使用编解码器模块打开具有特定编码的文件,但您必须事先知道它。

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

有没有办法自动检测文件使用的编码?

提前致谢

编辑: 谢谢大家非常有趣的回答。你可能也会对基于chardet的http://whatismyencoding.com/感兴趣(更多的网站是由瓶子python框架提供支持)

5 个答案:

答案 0 :(得分:21)

遗憾的是,通过查看文件本身,没有“正确”的方法来确定文件的编码。这是一个普遍的问题,不仅限于python或任何特定的文件系统。

如果您正在阅读XML文件,文件中的第一行可能会给您一些编码的提示。

否则,您将不得不使用一些基于启发式的方法,如chardet(其他答案中给出的解决方案之一),它试图通过以原始字节格式检查文件中的数据来猜测编码。如果您使用的是Windows,我相信Windows API还会公开尝试根据文件中的数据猜测编码的方法。

答案 1 :(得分:9)

您可以使用BOM(http://en.wikipedia.org/wiki/Byte_order_mark)来检测编码,或尝试使用此库:

https://github.com/chardet/chardet

答案 2 :(得分:4)

这是一个帮助您猜测编码的小片段。它猜测latin1和utf8之间相当不错。它将字节字符串转换为unicode字符串。

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

答案 3 :(得分:3)

来自Unicode DammitBeautiful Soup使用了chardet,但增加了一些额外的功能。

它尝试从XML或HTML文件中读取编码。然后它尝试在文件的开头寻找BOM或类似的东西。如果它不能这样做,它会使用chardet

答案 4 :(得分: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,