« Simple Calendar 2008 PDF & jQuery cheatsheet 別バージョン追加 | メイン | Yahoo! Pipes と jQuery で1年前のはてなブックマーク人気エントリを表示するガジェットを作ってみる --- その2 »

Yahoo! Pipes と jQuery で1年前のはてなブックマーク人気エントリを表示するガジェットを作ってみる --- その1

昨年末にYahoo! Pipes で任意のページをスクレイピングできるようになったという記事があり、気になっていました。

ってことで、そのすごさを実感するためにガジェットを作ってみることに。

ガジェットは、「1年前のはてブホッテントリ(人気エントリ)を表示する」という内容。前からちょっと考えていたネタです。

クライアント側では、これまた最近お気に入りのjQueryを使ってみることにします。

手順は、以下の通り。

  1. Yahoo! Pipes で、日付を渡すとその日の人気エントリをRSS返してくれるAPIを作成
  2. そのAPIを利用して、クライアント側で情報を表示

 

Yahoo! Pipes で、日付を渡すとその日の人気エントリをRSS返してくれるAPIを作成

なるべく簡単に、ということで、てっく煮さんで作成されている「Shinya talkをRSS化」というPipeをコピーさせてもらいます。(※海外Yahoo!のIDが必要になるので、Yahoo! Pipes を利用したい方はIDを取得してください。)

リンク先で、「Clone」リンクをクリックすると、yp_hb_gd_0001.png

Shinya talkモジュールが自分のPipesとして登録されます。

 

yp_hb_gd_0002.pngここで「Edit Source」をクリックすると、Pipeの編集画面になります。

yp_hb_gd_0003.png

オリジナルのPipeの流れは、

http://www.fujiwarashinya.com/talk/index.phpをFetchPageモジュールで取得し、<div id="center">以降を、<a id= をdelimiterとして分割」→「item.content をitem.title / item.description にコピーし、item.content を item.linkにリネーム」→「各title / link / description を正規表現でそれぞれにマッチした値に変更」→「Feed から < が含まれたものを削除」

というものです。

僕が作ろうとしているのは、http://b.hatena.ne.jp/hotentry?mode=daily&date=20050210のような動的に変更するパラメータをもったURLにアクセスし、スクレイピングしたいので、ユーザ入力としてdateを受け取り、モジュールの中でURLを組み立てます。

 

yp_hb_gd_0004.png

あとは、ページの内容にしたがって、Regexモジュールの正規表現を書き換えればOKです。

正規表現を適当に書いてしまうと、モジュールの実行速度にも影響がでるので気を付けましょう。実際、僕も最初に作ったPipeは、1回の実行に24secほどかかっていましたが、正規表現を修正することで 3sec 程度まで短くなりました。

↓完成したPipeはこちらです。

Pipes: Past Hatebu API

ちなみに各モジュールでの実行時間は画面下のDebugger の右上に表示されます。実行時間が遅いときは、各モジュールをクリックして、ここの値をチェックし、ボトルネックを見つけます。

 

yp_hb_gd_0005.png

 

そのAPIを利用して、クライアント側で情報を表示

今度は、作成したAPIをJavaScriptから利用してみます。

ガジェットを作る前に、まずは普通のhtmlから呼び出すことにしてみました。

ってことで、jQueryのgetJSON を利用してJSONを取得しようとしたのですが、ここで問題が。

jQueryのgetJSONを利用すると、アクセスするURLに自動的にnew Date().getTime() の値が付加されちゃいます。そうすると、Yahoo! Pipes 側でのキャッシュが効かなくなってしまうんですね。

このAPI でスクレイピングする先のページの情報は、基本的に変わらないものなので、都度アクセスしてしまうと無駄が多いし、レスポンスも悪くなってしまいます。

で、今度は↓こんなコードにしてみました。

s.src = 'http://pipes.yahoo.com/chrisryu/pasthatebu?date='+ds+'&_render=json&_callback=cb'
s.charset = 'UTF-8';
s.type = 'text/javascript';
s.id = 'jsonp';
$(document.body).append(s);

これで大丈夫だろうと思ったら、アクセスしているURLに変化がない(getTime()の値がついたまま)なんですね。なんでだろうと思ったら、$(document.body).append(s)で勝手にjQuery.ajaxが呼ばれていて、結果getJSONと同じ動きになっていました。

意味がなかったので、ソースを以下のように修正。

s.src = 'http://pipes.yahoo.com/chrisryu/pasthatebu?date='+ds+'&_render=json&_callback=cb'
s.charset = 'UTF-8';
s.type = 'text/javascript';
s.id = 'jsonp';
document.body.appendChild(s);

かなりべたな感じですが、しょうがないですね。

ということで、今日はここまで。連休中にはガジェット作るところまでいけると良いな。