Python版Yahooテキスト解析 APIライブラリをかな漢字変換に対応させました
まぁ需要はないと思うんですが一応。内部的にはWebService::Simpleみたいになってるんでサクッと対応できます。
ダウンロード
使い方
- import yahooapi.jlp as jlp
- client = jlp.JIMServiceAPI("your_apikey")
- result = client.conversion(sentence=u"かなかんじへんかんたいしょうのてきすとです")
- for i in result.Result.SegmentList.Segment[0].CandidateList.Candidate:
- print i
- #=>
- #かな
- #佳な
- #仮名
- #カナ
- #カナ
- #加奈
- #可奈
- #佳奈
- #香奈
- #香菜
- #華奈
- #花奈
- #哉
- #金
うむ。
Python版ニコニコ動画ライブラリを試しに公開してみる
※あくまで試験的に公開しています
まぁありきたりというか、なんというかなんですけどニコニコ動画の自分用ライブラリを以前から作っていました。公開してもよかったんですけど、需要があるかわかんないし、まとまってないですし、ニコニコ動画的にもこういうライブラリをつかってごにゃごにゃするのはちょっと・・・という感じらしいので公開してませんでした。
なんですけど、公開されてるライブラリもありますし、せっかくなんで試験的に公開しておけばなんかの役に立つかな、と思いまして。使ってくれる人が多かったりすれば、まとめなおしてCodeReposに突っ込むかもしれません。
ダウンロードしてみる奇特な方はどうぞ
必要なもの
easy_install mechanize
easy_install lxml
使い方
- import nicovideo as n
- client = n.NicoClient("mail", "pass", cookie_file="")
- print "nickname: %s" % client.nickname
- client.video("sm9").download(with_comments=True)
- print "search"
- for video in client.video_search("test", by=n.SEARCH_KEYWORD, sort=n.SORT_POSTED_AT, order=n.ORDER_DESC)[:10]:
- print video.title
- print "ranking"
- for video in client.video_ranking(by=n.RANKING_MYLIST, span=n.RANKING_DAILY, category="all")[:10]:
- print video.title
- print "new arrival"
- for video in client.video_newarrival()[100:110]:
- print video.title
- print "mylist"
- for video in client.video_mylist(2792158)[100:110]:
- print video.title
- print "random"
- for video in client.video_random():
- print video.title
こんな感じです。ニコニコ動画に負荷をかけないように、各httpリクエストの間に最低1秒待つので遅いです。ですが、できるかぎり情報はlazyにとりに行くようになっています。たとえば、video_searchでかえってくるVideoはidとタイトルの情報のみもっていて、その他の情報(lengthなど)にアクセスすると自動的にメタ情報を取りにいきます。メタ情報は
- print client.video("sm9").meta
- # =>
- description レッツゴー!陰陽師(フルコーラスバージョン)
- tags {'#text': '', u'tag': [u'\u9670\u967d\u5e2b', u'\u30ec\u30c3\u30c4\u30b4\u30fc\uff01\u9670\u967d\u5e2b', u'\u516c\u5f0f', u'\u904b\u55b6\u516c\u8a8d\u52d5\u753b', u'\u3053\u306e\u52d5\u753b\u306e\u3046\uff50\u4e3b\u306fnicovideo', u'\u97f3\u697d', u'\u4f1d\u8aac\u306esm9', u'\u03b2\u6642\u4ee3\u306e\u82f1\u96c4', u'\u5439\u3044\u305f\u3089\u6210\u4ecf', u'\u30de\u30a4\u30ea\u30b9\uff15\uff10\u4e07\u796d\u308a\u4f1a\u5834']}
- file_type flv
- comment_num 2618200
- l 320
- is_premium 0
- thread_id 1173108780
- view_counter 3839233
- link http://www.smilevideo.jp/view/9/350170
- nickname name
- user_id 00000
- title 新・豪血寺一族 -煩悩解放 - レッツゴー!陰陽師
- url http://smile-clb42.nicovideo.jp/smile?v=9.0468
- posted_at 2007-03-06 00:33:00
- video_id sm9
- thumb_type video
- watch_url http://www.nicovideo.jp/watch/sm9
- first_retrieve 2007-03-06 00:33:00
- mylist_counter 49956
- length 00:05:20
- thumbnail_url http://tn-skr.smilevideo.jp/smile?i=9
- ms http://msg.nicovideo.jp/10/api/
- time 1207225894
- done true
- #text
- last_res_body 1人だけじゃね
こんな感じのがとれます。基本的にthubnail APIからとってきて適当に型変換しています。thumbnail APIでの情報に加えて、file_typeなんかが付け加えられます。file_typeもちゃんと判別するのでflvでもmp4でもswfでももちろんちゃんとダウンロードできます。
ほかにもclient.video_newarrival()[100:110]とすると、自動的に何ページ目かを計算してそのページからhttpアクセスしてとりにいきます。
あと、ちょっとダウンロード中の表示がリッチな感じです。
ちょっと設計について
基本的に、NicoClientを拡張して機能を実装します。拡張方法はNicoClientExtensionクラスを拡張したクラスを定義する、以上です。これでNicoClientに自動的にクラス名をunderscoreしたメソッドが生えます。
たとえばVideoもNicoClientExtensionです。
- class Video(NicoClientExtension):
- URL_WATCH = NicoClient.URL_BASE + "watch/%s"
- URL_API_GET_FLV = NicoClient.URL_BASE + "api/getflv/%s"
- URL_API_GET_THUMB_INFO = NicoClient.URL_BASE + "api/getthumbinfo/%s"
- FILE_TYPE_RE = re.compile(".*/smile\?([a-z]{1})\=.*")
- def __init__(self, client, id, meta = None):
- self.client = client
- self.id = id
- self.meta = meta or {}
- # ...
という定義でclient.videoというメソッドが生えるという設計になっています。メタクラスにはこういう使い方があります。検索機能も、新着も、気まぐれも全部NicoClientExtensionとして実装されています。
問題点
- まとまってません。1ファイルに適当につめこんでいます。
- 全然テストしてません。
- sm9(陰陽師)が消されると動かなくなります
こんな感じです。
OreScriptがはやってるならパーサコンビネータの需要もあるのかな?
近頃、JavascriptでOreScriptなんてのがちょっとはやっていたりしまして。
OreScript書くのにある程度ちゃんと動くパーサコンビネータがあれば便利かも、とおもったので以前書いたパーサコンビネータをいじってみました。
変更点
- メソッド名などをHaskellにあわせた
- よくもわるくも、記号含有率をあげた(and -> $に、or -> l に)
- 相互再帰をサポートした
- 左再帰(chainl1)をサポートした
- 右再帰(chanr1)をサポートした
ということで、そこそこの用途に耐えるものになったと思います。
ダウンロード
完全にアンドキュメントです。すみません。ただ、ソースは200行くらいなんで見ればわかるかと。というか、HaskellのParsecのマニュアルを読めば基本一緒なので使い方がわかると思います。
サンプル
id:amachangさんが書いていたような数式パーサを定義してみましょう。
残念ながらLexerはつくっていないので、空白は受け入れられません。
- var ExprParser = Inforno.Parsec.Parsers.define(function(){with(this){
- var mul = function(a,b){return a*b;};
- var div = function(a,b){return a/b;};
- var add = function(a,b){return a+b;};
- var sub = function(a,b){return a-b;};
- this.numbers = many1( chrLike(function(c) { return (c>= '0' && c <= '9'); }) ) .ret(function(ns){
- return parseInt(ns.join(""));
- });
- this.expr = chainl1(p("term"), p("addop"));
- this.term = chainl1(p("factor"), p("mulop"));
- this.factor = (between(chr("("), p("expr"), chr(")"))) .l (numbers)
- this.mulop = (chr("*") .retval(mul)) .l (chr("/") .retval(div));
- this.addop = (chr("+") .retval(add)) .l (chr("-") .retval(sub));
- }});
- var test = "100*(100+200)/10";
- var parser = new ExprParser(test);
- var parseResult = parser.expr.parse();
- if(parseResult.success()) {
- alert(parseResult.result);
- // => 3000
- }
すごく、Parsecです・・・
こういうのを最近はやりのCodeReposでやればいいのかなあ。