Pythonでファイルのエンコーディングを取得する方法を知っている人はいますか?コーデックモジュールを使用して特定のエンコーディングでファイルを開くことができることは知っていますが、事前に知っておく必要があります。
import codecs
f = codecs.open("file.txt", "r", "utf-8")
ファイルに使用されているエンコーディングを自動的に検出する方法はありますか?
前もって感謝します
編集:非常に興味深い回答をありがとうございました。また、chardetに基づく http://whatismyencoding.com/ にも興味があるかもしれません(サイトの詳細はbottle pythonフレームワーク)を利用しています)
残念ながら、ファイル自体を調べてファイルのエンコーディングを決定する「正しい」方法はありません。これは普遍的な問題であり、pythonまたは特定のファイルシステムに限定されません。
XMLファイルを読んでいる場合、ファイルの最初の行mightは、エンコーディングが何であるかについてのヒントを提供します。
それ以外の場合は、 chardet (他の回答で示されているソリューションの1つ)のようなヒューリスティックベースのアプローチを使用する必要があります。 Windowsを使用している場合、Windows APIは、ファイル内のデータに基づいてエンコードを推測するためのメソッドも公開していると思います。
BOM( http://en.wikipedia.org/wiki/Byte_order_mark )を使用してエンコードを検出するか、次のライブラリを試してください。
これは、エンコーディングを推測するのに役立つ小さなスニペットです。 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))
nicode Dammit from Beautiful Soup があり、これは chardet を使用しますが、いくつかの追加機能を追加します。
XMLまたはHTMLファイル内からエンコーディングを読み取ろうとします。次に、ファイルの先頭でBOMなどを検索しようとします。それができない場合は、 chardet を利用します。
#!/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,