え〜、すんません。
今回は、ネタがネタだけに、取り扱い注意ください。(特に最後の方)
実は、本音でやりたかったのは、
- 自分は、いつもRSSを使って、色んな興味のある箇所をチェックしてます。(それで、Plaggerも使ってます)
- けど、前々から気に食わなかった事の一つに、「英文が まともに読めないので、英語のRSSをチェックできない」ってのがありました。
- 機械翻訳サービスとRSSデータを組み合わせたら、英語のRSSもチェックできるのになぁ。
- PlaggerはPerlで出来ているんで、よく判らない。なので、勉強がてらhabuさんを使ってみた。
という事です。
で、最初に結論から言いますと、
- 英文RSS→機械翻訳→和文RSSは出来ます。
- けど、どうみてもDOM行為スレスレです。なので、今回のネタは、サンプルとして見てください。
- 将来、どこかのRSSフィードをしてくれる会社と機械翻訳サイトが提携して、英語サイトに対して英和データをキャッシュ&RSS配布するサービスが登場するのを、絶望しながら期待しましょう。
「この翻訳文は、xxxの技術を使っています」ってな感じで広告してもらって…のは、虫が良すぎるかなぁ。 - あるいは、カスタマイズできる、オフラインな機械翻訳ソフトを使いましょう。
という事です。
habuって何だ?
一言で言うと、Plagger for Pythonって感じです。
- 【ハウツー】「habu」 - Python版PlaggerでRSSを加工する (1) 「habu」とは何か? - 概要 | エンタープライズ | マイコミジャーナル
http://journal.mycom.co.jp/articles/2007/08/29/Python_habu/index.html - FrontPage - habu Wiki @ SF.jp
http://sourceforge.jp/projects/pyhabu/wiki/FrontPage
開発は、Days of Lirisさんです。
Windows上にPlaggerやhabuを入れて動かしてみての感想は、
- Plaggerは高機能。けど、アップデート怖いっす。すごい数のライブラリを入れないといけないんですよね。
(まぁ、普段Perlを使ってないんで、問題が起きた時、どう対処すりゃいいか判んないのが大きいんですけど) - habuは基本を押さえた感じ。けど、ライブラリの数が少ないので、そんなにアップデートは怖くない。
です。
habuをインストールして使ってみる
インストールと使い方は、上に挙げたMYCOMとWikiの記事で十分です。
私の場合は、Subversionを使って、コードをダウンロードし、
$ svn checkout http://svn.sourceforge.jp/svnroot/pyhabu/trunk habu
ライブラリをポチポチダウンロードしては、動作させてみてました。
動かした際、何のライブラリが足りないか、エラーメッセージが出るので、上記記事で紹介のあるライブラリのURLからゲットすれば良いです。
F:\Wacky\Test\python\habu\habu>python runhabu.py Traceback (most recent call last): File "runhabu.py", line 1, in ? from twisted.internet import reactor, defer ImportError: No module named twisted.internet ← Twistedが足りないって言ってる
Windowsで動かす場合は、配布されているのが、セットアップ形式のexeタイプばっかりなので、ダウンロードしてダブルクリック&インストールを繰り返せばOKです。
SQLObjectだけは、easy_installを使いますが、それもWeb siteにインストール方法が事例と一緒に掲載されているので簡単です。
実行はとにかく、habuフォルダ上でコマンドプロンプトを起動して、"python runhabu.py"すれば良いです。
うまく行けば、以下のように出力され、
F:\Wacky\Test\python\habu\habu>python runhabu.py 2008/01/01 16:07 +0900 [-] Log opened. 2008/01/01 16:07 +0900 [-] Started habu with Task Mode 2008/01/01 16:07 +0900 [-] habu.webutils.getPage : http://dev.ariel-networks.com /Members/blog_update/RSS 2008/01/01 16:07 +0900 [-] Starting factory <HTTPClientFactory: http://dev.ariel -networks.com/Members/blog_update/RSS> 2008/01/01 16:07 +0900 [-] habu.webutils.getPage : http://www.liris.org/blog/RSS 2008/01/01 16:07 +0900 [-] Starting factory <HTTPClientFactory: http://www.liris .org/blog/RSS> 2008/01/01 16:07 +0900 [HTTPPageGetter,client] Stopping factory <HTTPClientFacto ry: http://www.liris.org/blog/RSS> 2008/01/01 16:07 +0900 [HTTPPageGetter,client] Thread Joined 2008/01/01 16:07 +0900 [-] Stopping reactor 2008/01/01 16:07 +0900 [HTTPPageGetter,client] Stopping factory <HTTPClientFacto ry: http://dev.ariel-networks.com/Members/blog_update/RSS> 2008/01/01 16:07 +0900 [-] Main loop terminated.
同じフォルダに、"out.rss"ファイルが出来上がります。
カスタマイズする
実は、先ほどの"python runhabu.py"というのは、"python runhabu.py habu.cfg"しているのと同じでして、habuは、"habu.cfg"に記述されている設定内容を読み込んで動いていたんです。
なので、オリジナルな設定ファイル、例えば"test.cfg"を作って動かしたいなら、"python runhabu.py test.cfg"とすれば良いです。
設定ファイルの記述方法は、Wikiページに記述されているので、それを参考にすれば良いです。
Plaggerで記述した事があるなら、そんなに難しくありません。
実は、よく理解してないのが、pipelineセクションの説明にある、"一つのプロセス内で複数の加工方法を同時並行で処理できます"って説明でして、これってスレッドを叩き起こして、「データ」を「指定された加工方法」順に繋いでいるってイメージかな?と思ってます。
プラグインは、subscription / filter / publisher の3カテゴリに分かれてまして、
- 入力 : subscription
- 変換 : filter
- 出力 : publisher
って捉え方でOKかな?と思います。
プラグインは、全て同じような構造になってまして、例えば何もしないプラグインは、どうも↓こんなのでOKっぽいです。
class Hoge(object): def __init__(self, config, environ): pass def execute(self, content): return content def create(config, environ): return Hoge(config, environ)
プラグインを作る場合、Pythonデバッガ(pdb)モジュールを突っ込んで、一旦動作を止めて内部の動きを観測するのが、理解の早道だと思います。
例えば、↓こんな風に。
import pdb # 追加 class Hoge(object): def __init__(self, config, environ): pass def execute(self, content): pdb.set_trace() # 追加 return content def create(config, environ): return Hoge(config, environ)
実行すると、"pdb.set_trace()"の箇所で停止するので、内部を観測すれば良いでしょう。
以下は、execute呼び出しで一旦停止させ、content引数の内部情報を観測している様子です。
F:\Wacky\Test\python\habu\habu>python runhabu.py test2.cfg 2008/01/02 18:02 +0900 [-] Log opened. 2008/01/02 18:02 +0900 [-] loading modules... 2008/01/02 18:02 +0900 [-] done to preload module. 2008/01/02 18:02 +0900 [-] Started habu with Task Mode 2008/01/02 18:02 +0900 [-] Start Line : rss_fetcher 2008/01/02 18:02 +0900 [-] Remaining Context Num : 2 2008/01/02 18:02 +0900 [-] Get executeCallback : rss_fetcher 2008/01/02 18:02 +0900 [-] Event Fired : 3 2008/01/02 18:02 +0900 [-] remaining context num : 1 2008/01/02 18:02 +0900 [-] Remaining Context Num : 2 2008/01/02 18:02 +0900 [-] > f:\wacky\test\python\habu\habu\habu\filter\hoge.py( 9)execute() 2008/01/02 18:02 +0900 [-] -> return content dir(content) 2008/01/02 18:04 +0900 [-] (Pdb) ['__class__', '__cmp__', '__contains__', '__del attr__', '__delitem__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattr__' , '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__ ', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__ ', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__slotnames__', ' __str__', '__weakref__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keymap', 'keys', 'pop', 'popitem', 'set default', 'update', 'values'] content.keys() 2008/01/02 18:04 +0900 [-] (Pdb) ['feed', 'encoding', 'bozo', 'version', 'namesp aces', 'entries'] content["entries"].keys() 2008/01/02 18:04 +0900 [-] (Pdb) *** AttributeError: 'list' object has no attrib ute 'keys' len(content["entries"]) 2008/01/02 18:05 +0900 [-] (Pdb) 25 content["entries"][0].keys() 2008/01/02 18:05 +0900 [-] (Pdb) ['updated', 'subtitle', 'updated_parsed', 'publ ished_parsed', 'title', 'feedburner_origlink', 'author', 'links', 'content', 'ti tle_detail', 'link', 'published', 'author_detail', 'id'] content["entries"][0]["title"] 2008/01/02 18:05 +0900 [-] (Pdb) u'TotT: Avoiding friend Twister in C++'
構造を観測すると判りますが、連想配列とリストの組み合わせで出来ています。
これなら、プラグインを作るのも、結構簡単ぽいです。
機械翻訳プラグインを使って、英文RSSを和文変換する
コードは、勝手ながら、以下に投稿させてもらいました。
(Days of Lirisさん、勝手に使わさせてもらいました。済みません)
- Issue 1 - pyhabu-plugins - Google Code
http://code.google.com/p/pyhabu-plugins/issues/detail?id=1
内容としては、trans2text.pyプラグインから、MachineTrans.pyモジュールを読み込み、英文データを機械翻訳にかけ、和文データを取得して、テキストファイルに落とす代物です。
まぁ、詳細は、投稿先を読んでください。
機械翻訳するMachineTrans.pyモジュールは、以下のように動きます。
- MachineTransクラスを生成する(引数use_siteに、文字列を渡すと、どこの機械翻訳を使うか指定できる)
- get_transメソッドに、英文データを渡すと、機械翻訳サイトに行って、和文データを受け取り返す
機械翻訳サイトでのデータの受け渡しには、SleipnirのCOMインタフェースを制御しています。
IEのCOMインタフェースより、ドキュメントの読み取り完了の判定が楽だったのと、セキュリティ制御が楽だったのが、その理由です。OnAmbientPropertyを操作して云々なんて、面倒で面倒で。
コードはActiveX(COM)&Pythonパワー全開なので、159行程度です。無駄な部分多いですが、オッpy初心者って事で勘弁して下さい。