Python
Chardet
Cchardet

Python3.3.1でcChardetとpython3-chardetを使ったメモ

More than 1 year has passed since last update.

chardetというPythonのライブラリがある。bytes列を入力すると、bytes列が何の文字コードで書かれた文字列をエンコードしたものだったのかを推論することができる。

chardetをPython3で使おうと思ったが、公式はまだPython3に対応していない。

探してみたところ、python3-chardetという、chardetをforkしたライブラリを見つけたのでそれを使うことにした。

※追記 cChardetのほうが速いのでそっちのほうが使いやすい。記事の下に追記した。

インストール

githubからダウンロードしてインストールする。

$ git clone git@github.com:bsidhom/python3-chardet.git 

で作ったディレクトリで

$ python setup.py install

するとインストール完了。

実験

ipython3
import chardet

chardet.detect('abc'.encode('utf-8'))
> {'confidence': 1.0, 'encoding': 'ascii'}

chardet.detect('あいうえお'.encode('utf-8'))
> {'confidence': 0.9690625, 'encoding': 'utf-8'}

chardet.detect('あいうえお'.encode('Shift-JIS'))
> {'confidence': 0.5, 'encoding': 'windows-1252'}

ちゃんと動いた。'あいうえお'.encode('Shift-JIS')がwindows-1252だと判定されたのはちょっと不安だが、confidenceが0.5なのでchardet自信も半信半疑なのだろう。文が短すぎたので仕方がない。

Webページをスクリプティングするときに使えるか、さらに実験を行った。

対象となるWebサイトは価格.com http://kakaku.com/ に決定。Shift_JISを使っているのでちょうどよい。

ipython3
import chardet
import requests

r = requests.get('http://kakaku.com')
chardet.detect(r.content)
> {'confidence': 0.99, 'encoding': 'SHIFT_JIS'}

うまく判別してくれた。'あいうえお'.encode('Shift-JIS')の例と異なり、windows-1252ではなくSHIFT_JISと正確に判断してくれたのは、Webページ全体を対象とした長いbytes列を対象にしたからと思われる。confidenceも高くなった。

追記

cChardetというC拡張のPythonライブラリがあることにあとで気づいた。Python3で使える。PyYoshiさんすごい。

pypiにあるので https://pypi.python.org/pypi/cchardet/ pipで取ってこれる。

$ pip install cchardet

せっかくなので、さきほどの価格.comのトップページを利用して、速度比較を行った。コードは以下の通り。

compare.py
import chardet
import cchardet
import requests
import time

if __name__ == '__main__':
    r = requests.get('http://kakaku.com')
    begin_time = time.clock()
    guessed_encoding = chardet.detect(r.content)
    end_time = time.clock()
    print('chardet: %f, %s' % (end_time - begin_time, guessed_encoding))

    begin_time_of_cc = time.clock()
    guessed_encoding_by_cc = cchardet.detect(r.content)
    end_time_of_cc = time.clock()
    print('cChardet: %f, %s' % (end_time_of_cc - begin_time_of_cc, guessed_encoding_by_cc))

そして結果は以下のようになった。

chardet: 1.440141, {'confidence': 0.99, 'encoding': 'SHIFT_JIS'}
cChardet: 0.000589, {'confidence': 0.9900000095367432, 'encoding': 'SHIFT_JIS'}

圧倒的ではないか。

結論

cChardetを使おう!!!