iso tank 2007年 12月

パイソンPython

相変わらずいつなんどき何に興味が向くかわけのわからないワタクシ。また最近になってPythonに興味わいてきた。

で、今は何してるかっていうとついさっきまでURLエンコーディングについて考えてた。 URLエンコーディングっていうのはほら、よくWIKIとかGOOGLEとかの類にあるURLの後ろに"%"と英数字がいっぱいついてるやつ。あれのことなんです。 あれは2バイト文字をサーバとかそういうのが解釈できるように符号化したもので、「URLエンコード」でググると、簡単にURLエンコーディングができるサイトがぼろぼろ出てくるです。 でまぁ、Pythonでもできるのかなーってふと気になった。やってみた。ちょっと1週間近くつまづいた挙句にぱっと閃いたら30分くらいで完成した。

http://iso.tank.jp/sandbox/py/urlende.cgiで、エンコードしたい文字列を入力して文字コードを選んで送信すればいいです。 その文字コードで変換したわけのわからない文字列があなたを出迎えてくれます。逆にわけのわからない文字列をわけのわかる普通の単語に戻す(デコードする)こともできます。 この時、変換元の文字コードがわからないとエラーを吐き出すので注意。

エンコードは一行で済んだ。なんかある意味すごいわ。でもUnicodeの扱い方がちょっとよくわからなくて混乱した。

文字列 = urllib.quote_plus(unicode(文字列,'utf-8').encode(文字エンコード),':;/')

urllibっていうのがモジュール。quote_plusっていうのがurllibモジュールについてる関数。unicodeは標準でついてる関数。encodeはメソッド。 あ、日本語のところには変数がはいります。quote_plusの第二引数":;/"はエンコードしない記号。仕様は、 「入力されたUTF-8の文字列をUnicode化し、できあがったそれをユーザーお好みの文字コードに変換し、それをURLエンコードしちゃいなさい?」 となるです。もしUTF-8以外の文字列が入力されると多分エラーを吐き出すかも。HTMLそのものがUTF-8で作られてるから、入力される文字もUTF-8じゃないとおかしいんだけどぬー。

デコードはこう。

文字列 = unicode(urllib.unquote_plus(文字列),文字エンコード).encode('utf-8')

「入力されたURLエンコードされているはずの文字列を普通の文字列に直して、できあがったお好みの文字コードで構成されているはずの文字列をUnicode化し、それをUTF-8に変換しなさい?」 という仕様。だいたい。エンコードもデコードも「はず」という前提で動いてるから、あまり無茶はしてやれない。っていうかデコードも一行で済んでますね。色々すっ飛ばしてるからね。

で、要所要所にちりばめられている「unicode」。まずは、「Unicode」と「UTF-8」は"違うもの"ということを理解する必要があるようです。 よくはわからないけどUnicodeというのは文字コード表そのもの、つまり「文字コード本体」のことで、UTF-8というのは「符号化方式」えーとつまり「変換方法」のこと、みたいな。 結局どういうことかといえば、ある文字コードから他の文字コードに変換したりするのに、いったんUnicode表記にしないと他の文字コードに変換できないっぽいらしいということ。

ENCODE: UTF-8→Unicode→お好み→URL文字列
DECODE: URL文字列→お好み→Unicode→UTF-8

こゆこと。

あと、Pythonは標準でエラー処理について色々と充実している。っぽい。

try:
    文字列 = unicode(urllib.unquote_plus(文字列),符号化方式).encode('utf-8')
except UnicodeError:
    メッセージ = "文字列変換誤り。正しひ符号化方式を指定下さるやう。"

TRY節を実行して、exceptにあるエラー(この場合はUnicodeErrorというエラー)が発生した場合はEXCEPT節を実行する。EXCEPT節はいくらでもいっぱいつくれる。っぽい。 この文の後ろに

except:
    メッセージ = "何だか解りませんが、兎に角御免なさい。"

と書いておくと、UnicodeError以外のエラーは全部このように処理されるという仕組み。うーん面白い。

そんなわけで、http://iso.tank.jp/sandbox/py/urlende.cgiでなんか変なエラーとかでたら教えてほしいのです。よろしく。

2009/12/24追記 URL変えてました。忘れてた。