chardetで文字コードを自動変換する
curlなどで取得したテキストを自動的にターミナルの文字コード(たとえばUTF-8)に変換したい場合がある。 このような場合には、Pythonのchardetモジュールが使える。 chardetは、Mozilla Firefoxで使われている文字コード判定アルゴリズムをPythonモジュールとして移植したものである。
chardetのインストール
DebianやUbuntuでは最初からインストールされている。
$ sudo apt-get install python-chardet Reading package lists... Done Building dependency tree Reading state information... Done python-chardet is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 35 not upgraded.
文字コードを自動判定し、デコードする
次のようなPythonコードを書き、test.pyとして保存する。
import sys import chardet text = sys.stdin.read() result = chardet.detect(text) print result print text.decode(result["encoding"])
iconvコマンドでShift_JISに変換したテキストをスクリプトに与えると、次のようになる。
$ echo -n 日本語 | iconv -f utf-8 -t shift_jis | python test.py {'confidence': 0.99, 'encoding': 'SHIFT_JIS'} 日本語
Shift_JISと判定され、デコードに成功している。
シェル関数にしてみる
次のような関数を.bashrcなどに書くことで、シェル関数として使うことができる。
cats() { local CODE read -r -d '' CODE <<"__EOF__" import sys, locale, chardet text = sys.stdin.read() locale = locale.getdefaultlocale() or ('en_US', 'UTF-8') result = chardet.detect(text) sys.stdout.write(text.decode(result['encoding'], 'replace').encode(locale[1])) __EOF__ cat "$@" | python -c "$CODE" }
ためしに、GB2312で書かれている騰訊QQのHTMLテキストを取得してみる。
$ echo $LANG en_US.UTF-8 $ curl -s http://www.qq.com/ | head <!DOCTYPE html> <html lang="zh-CN"> <head> <meta content="text/html; charset=gb2312" http-equiv="Content-Type"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>��Ѷ��ҳ</title> <script type="text/javascript"> if(window.location.toString().indexOf('pref=padindex') != -1){ }else{ if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))){
HTMLテキストがGB2312で書かれているのに対し、ターミナルの文字コードがUTF-8であるため、title要素の中身が文字化けしていることがわかる。
ここで、定義したシェル関数にパイプで繋いでみる。
$ curl -s http://www.qq.com/ | head | cats <!DOCTYPE html> <html lang="zh-CN"> <head> <meta content="text/html; charset=gb2312" http-equiv="Content-Type"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>腾讯首页</title> <script type="text/javascript"> if(window.location.toString().indexOf('pref=padindex') != -1){ }else{ if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))){