|
|
||
別の大きめの機能のリリース準備中なんですが、片手間に作ってみました。フレーム使ってるサイトとか今のところ動きませんが、おおむね上手く動くと思います。有志が作ってくれた野良フィード、と同程度のクオリティのものを自動で作れます。
リリースが早かったので「前々から作ってたのかな」みたいな反応もいくつか見ましたが、そういうわけではないです。ただ、過去に似たようなコードを書いたことがあるのですんなり出来ました。
アルゴリズムはこれに改良を加えたものです http://la.ma.la/blog/diary_200705301424.htm
実装開始 http://twitter.com/bulkneets/status/8240819145
リリース http://twitter.com/bulkneets/status/8358993519
twitterでフィードを吐いてないサイトのURLを募集して参考にしました。協力してくれた方に感謝します。よく考えたらなんでもRSSで購読されてるサイトを使えば良いので必要なかったかもしれない。
とりあえず動くものは3時間ぐらいで出来たと思います(面接試験に調度良い)、あとは2日ぐらいかけて精度の調整をやりました。既存のサービスと何が違うの、みたいなのがFAQだと思うのでいくつか比較してみます。
既存の似たようなサービスは沢山あると思うのですが、
というような具合で、タダ乗りしても良さそうなのが無かった。タダ乗りしても良さそうなサービスはこれらと逆の条件を満たしているサービスです。既存のサービスでタダ乗りしても良さげなのがあるならリンク張って終わりというのも考えたのですが、上記と逆の条件を全て満たすようなサービスが無かったので、片手間に作れそうだしせっかくなのでこの際作っておくか、ということになりました。
単体で収益挙げられるような要素が無いですけども、readerの付加価値が上がるので利益が出なくてもまあ問題ないでしょう。ラボですし。
日本語のサイトでも変換出来ます。
http://googlereader.blogspot.com/2010/01/follow-changes-to-any-website.html
http://blogs.itmedia.co.jp/saito/2010/01/google-reader-6.html
any websiteって言うので、なんかインパクトが大きかったみたいで「LDRにも似たような機能を希望」とか要望が飛んできた。それで作ったので、後追いといえば後追いですが、
http://www.google.com/support/reader/bin/answer.py?hl=en&answer=172963
"Currently, only English-language content in HTML format is supported."としっかり書いてあります。英語のサイトに関しても、生成されたフィードが読みやすいとは思えなかった。実際に試さないで「これはすごい」とか「これは便利」とか記事を書くのは止めませんか。
現状英語のサイトにしか対応してないのを知らないで試して残念な思いをしている人がチラホラいる。
http://d.hatena.ne.jp/Imamura/20100202/googlereaderRSS
Page2FeedはGoogle Readerでも上手く動くみたいです。独立したAPIなのでタダ乗り歓迎です
http://bardiche.posterous.com/bbrss
なんでもRSSの問題点をいくつか挙げます。
フィードリーダーから記事をそのまま開いたり、ソーシャルブックマークの情報を参照しやすくするために、なるべく記事のリンクを抽出します。実用性を重視してます。
逆になんでもRSSとは違って日付情報を解析してないので、記事の更新時刻が正確ではありません。フィードリーダーが取得した時刻になるでしょう。
クロールして差分を記録するタイプ(page2rss.comやGoogle)は
過去記事の蓄積と新着部分の判別はRSSリーダー側に任せて、HTMLをフィードに変換する処理は切り分けてしまった方が良いだろうと判断しました。必要なのは帯域とCPUパワーなので、もしアクセスが異常に増えても対応しやすい。1世代分は保存して学習に使った方が精度が上がるかな、とは思ってます。
スコアが高いのだけを出力すれば本文のみのフィードも作れるのですが、意図的に本文以外も入れています。生成されたフィードは未読管理機能があるフィードリーダーで使う前提です。本文以外の要素もフィードに入る場合がありますが、一度既読になってしまえば現れないからです。なので、例えばティッカーやFirefoxのライブブックマークには適さないでしょう。
今のところしてません。例えばサイトごとの定義を作るとメンテナンスコストがかかります。ベースとなるアルゴリズムが優秀であれば、上手くいかないサイトに対してだけパッチを作れば良いことになります。定義作るとしてもタイプ(ニュース、日記、掲示板、など)に応じて各種閾値を調整するみたいな感じになると思います。学習や人力による調整を行わなくても、デフォルト状態でとりあえず良い感じのフィードを出力するのを目的としてます。
元のコードがJavaScriptなんで今度はPerlからJavaScriptに移植すれば何かと役に立つかもしれない。JS実行したDOM構築後のフィード作ったり認証が必要なページをブラウザで解析して送ったりとか。
もう少し技術よりの解説を書くかもしれない。
一つのAnyEvent::Handleをコネクション切らないで使いまわして、JSONRPCなんかでリクエスト送りまくったりした場合に、書き込みバッファが際限なく溜まりすぎてサイズが大きく確保されたまま500MBとかになってしまって困ったのでメモする。
書き込みバッファが掃けたタイミングで、新しいイベントを発火させるようにする。
AE::timerとか使って適当なタイミングでこういうコードを呼ぶ。
if($hdl->{wbuf} eq ""){ delete $hdl->{wbuf}; $hdl->{wbuf}=""; }
もしくは適当なタイミングでコネクション張りなおせば良い。ものすごい勢いで書き込んでいたらどの道メモリを食いつぶすのでオススメできない。
こういうコード挟んで書き込みイベントにwaitを入れる。wbufが8MB以上だったらsleepする。
while(1024 * 1024 * 8 < length $hdl->{wbuf}) { warn "wait for write"; Coro::Timer::sleep 0.05; }
誰か作ってるだろと思ってギャラリー検索したけど見つからなかったので作った。
https://chrome.google.com/extensions/detail/ifekfcjbnkflfndoahjigdhlhgndkncb
os0xさんが技評の連載のサンプルで作ってたやつの改造、あとGoogle Mail Checkerのソースなども参考にした。
http://gihyo.jp/dev/serial/01/chrome-extensions/0001
変更点は
一方的にスクリプトを適用するのは簡単で、bookmarkletやGreasemonkeyスクリプト相当の拡張は簡単に作れそう。
ただし、拡張側から現在表示中のタブの中身のDOMを直接参照したりは出来ないっぽかった。
tabオブジェクトのプロパティからURLやtitleは取れるが、DOMは取れない。
http://code.google.com/chrome/extensions/tabs.html#type-Tab
これはセキュリティ上の制約と言うことだろうから
と言う方法を取った。
FeedBurnerにGoogle Analyticsと連携する機能が追加されて、FeedBurnerのアクセス解析機能を使っていた人が、自動的にこのオプションを利用するように設定変更されています。
http://blog.fkoji.com/2009/11141538.html
で、特になにも影響がないなら勝手に便利な機能は勝手に有効にしてくれれば良いと思うのですが、影響があります。
http://feedproxy.google.com/~r/*****/*******/hogehoge.html
というアクセス解析用のリダイレクトURLの飛び先が
http://example.com/blog/hogehoge.html?utm_source=feedburner&utm_medium=feed&utm_campaign=...&utm_content=...
みたいに変更されています。このため
という現象が起こります。
こんな具合です。
http://www.google.co.jp/search?q=inurl%3Autm_source%3Dfeedburner
http://adsenseforfeeds.blogspot.com/2009/11/afternoon-frank-hey-howdy-george.html
コメント欄のやりとり
Chris said...
Question: does this explain why anyone who clicks through to my site via my feed hits a URL with the suffix utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A%20
etc?
Seems like a sloppy way to implement this. Any way I can get rid of that extra baggage?
November 16, 2009 8:50 PM
担当者っぽい人の返事
Steve Olechowski said...
... 前略 ...
@Chris - this post shows you how to turn it off
everyone - else - yes we hear you and are working on it!
November 17, 2009 7:52 AM
「この記事で無効化する方法を説明しているよ」と一蹴されている。多分この担当者は意味が分かってないか、あるいは意図的に問題を無視してる。
何でわざわざユーザーが操作して無効にしないといけないんだ?勝手に有効にしておいて。utm_***というのは、少なくともGoogle Analyticsを使ってない人には全く無意味なクエリで、そのような人にとってはURLが汚くなるだけで完全に無駄な機能だ。デフォルトはオフであるべきで、この機能を有効にしたい人が「デメリットを承知した上で」有効にすべきだろう。なぜこのような大きな副作用の伴う変更をユーザーの同意を得ずに勝手に行うのか疑問に思う。恐らくデフォルトオンになっているのは、Analyticsの管理画面を見ている人に新機能が登場したことに気付かせるためだろう。デフォルトオンでも全然かまわないよ、URLが汚れないなら。
クエリにトラッキング用のパラメータを含めるというのは、簡単だが、悪く言えば「手抜き」の方法だ。URLに余計なクエリを付けずに同等の機能を提供できるかと言えば、出来ると思う。なぜならFeedBurnerもAnalyticsもGoogleが運営するサービスだからだ。FeedBurnerのアクセス解析結果をGoogle Analyticsに反映させるならアカウントを紐づけてアクセス解析結果を交換するようにすればいい。精度は下がるかも知れない、が、クエリ付きの状態でコピーアンドペーストされて様々なサービスに伝搬してしまう方が、よっぽど精度を下げることになると思う。
拡張側とページ側はプロセスが分かれているので、直接アクセスすることができません。これはセキュリティ上の理由でもあり、実装上の都合でもあり。
chrome.tabs.executeScriptはcontent_script相当の処理を拡張コンテキストからプログラマブルに実行するAPIなので、ブックマークレットとはコンテキストが異なります(ページ側のコンテキストと分かれている)。
ブックマークレット(ページ側のコンテキスト)としてスクリプトを実行したい場合は、chrome.tabs.update({url:'javascript:/**/'}); のようにすると実行できます。
もう少し詳しい話はこちらに書きました http://groups.google.co.jp/group/chromium-extensions-japan/browse_frm/thread/eefc287888862afb