2007/12/16
指定したURLのタイトルを取得するAPIをYahoo! Pipesで作った
(管理人日記)
またYahoo! PipesのFetch Pageモジュールを使って実現した新しいAPI。
pagetitle API
今回作ったのは以下。
これは何か
URLを指定すると、そのページのタイトルを、htmlのtitle要素(をスクレイピングで取得)、はてなブックマーク、livedoorクリップ、del.icio.us、Buzzurlから取得し、返します。データはRSS、JSON、JSONPで取得できます。
たとえば、当サイトのURL(http://muumoo.jp/)を指定すると、この記事を書いてる時点では以下の内容が返ります。
- title: page, description: むぅもぉ.jp
- title: hatena, description: むぅもぉ.jp
- title: livedoor, description: むぅもぉ.jp
- title: del.icio.us, description: むぅもぉ.jp
この4件。titleフィールドに取得元(page / hatena / livedoor / del.icio.us / buzzurl)、descriptionフィールドにページのタイトルが入っています。上記の例でbuzzurlが無いのは、誰もBuzzurlにこのURLを登録していないためです。
使い方
このAPIの呼び出し方は以下のような感じ。
http://pipes.yahoo.com/poolmmjp/pagetitle?url=(URL)&_render=json&_callback=hoge
上記はJSONPで呼び出す場合の例。JSONの場合は_callbackパラメータを削除し、RSSの場合はさらに_renderパラメータを「rss」にしてください。
メモ
通常は「page」のアイテムだけを見ればいいと思いますが、これはYahoo! PipesのFetch Pageモジュールを使って取得しているので、
- robots.txt等でYahoo! Pipesのクローラをブロックしている
- URLがhtml(やxhtml)じゃない(画像とかね)
- htmlをYahoo! Pipesがパースできなかった(文法がメチャクチャだとか)
- そもそもtitle要素を書いてない
などの場合にスクレイピングに失敗します。そういうとき、もしそのURLがソーシャルブックマークに登録されていたら、そっちのデータが使えるわけです。
例えば、「このAPIから取得できた文字列のうち、一番文字数が多いものをタイトルして扱う」とかが良いかも知れない。まあ文字数が多いからってわかりやすいとは限らないけど。
仕組み
ここから先はYahoo! Pipesに興味がある人向け。このPipeのソースは以下です。あまりに巨大なので(3000×1203ピクセル)、開くときは要注意。まあ容量は116KBなのでそうでもないけど。
一応、何かの役に立つかも知れないので解説を書いておきます。
- 最上部 : URLを入力(URL Input)
-
左から1番目(スクレイピング部)
- ページを取得し、title要素以下を抜き出す(Fetch Page)。title要素に属性があるかも知れないから、あえて開始タグの閉じカッコは書かない。
- その内容をtitleフィールドとdescriptionフィールドにコピー(Rename)。本当は空っぽのtitleフィールドを作りたいが、そういう機能はYahoo! Pipesには無いので(Loop+ItemBuilderでも無理っぽい)、ここでとりえず既存のフィールドをコピーする形で作った。
- titleフィールドに「page」という文字列を入れ、descriptionフィールドはhtmlタグらしき文字を消去(Regex)。
-
左から2番目(はてなブックマーク部)
- URL中の「#」を「%23」に変換(String Replace)。こうしないとはてブ用の正しいURLが作れない。
- はてブのエントリページのフィードのURLを作る(URL Builder)。書式は「http://b.hatena.ne.jp/entry/rss/(URL)」。
- データを取得する(Fetch Data)。Fetch Feedを使うと、フィードのアイテム部しか見えない。今回はフィードのタイトルの部分が欲しいので、あえてFetch Dataを使い、フィードをただのXMLとして扱う。channel要素内のtitle要素がタイトルなので、ここを取り出す。ここには「はてなブックマーク - (ページのタイトル)」という書式で入っている。
- さっきと同様に、titleフィールドとdescriptionフィールドにコピー(Rename)。
- titleフィールドに「hatena」という文字列を入れ、descriptionフィールドは先頭の「はてなブックマーク - 」の文字を削除する(Regex)。
-
左から3番目(livedoorクリップ部)
- LDCのJSON-APIのURLを作る(URL Builder)。書式は「http://clip.livedoor.com/api/json/comments?link=(URL)」。
- データを取得する(Fetch Data)。このURLはJSONなので、Fetch Dataを使い、title要素の中身を取り出す。
- さっきと同様に、titleフィールドとdescriptionフィールドにコピー(Rename)。
- titleフィールドに「livedoor」という文字列を入れる(Regex)。
-
左から4番目(del.icio.us部)
- 外部Pipeとしてpagetitle API from del.icio.usを呼び出し、タイトルを取得する。具体的な取得方法は2007.12.15の日記を参照。
- titleフィールドにタイトルが入ってくるので、これをdescriptionフィールドにコピーする(Rename)。今回はtitleフィールドが最初からあるので、作らなくて良い。
- linkフィールドは不要なので削除(空っぽに)し、titleフィールドに「del.icio.us」という文字列を入れる(Regex)。
-
左から5番目(Buzzurl部)
- BuzzurlのJSON-APIのURLを作る(URL Builder)。書式は「http://api.buzzurl.jp/api/counter/v1/json?url=(URL)」。
- データを取得する(Fetch Data)。なぜかtitle要素の中身を取り出そうとしたら空っぽになったので、ここはルートから丸ごと取り出す。
- Fetch Dataのところでtitle要素を取り出せなかったので、ここで抜き出す(Sub-element)。
- さっきと同様に、titleフィールドとdescriptionフィールドにコピー(Rename)。
- titleフィールドに「buzzurl」という文字列を入れる(Regex)。
-
最下部
- 上記の5本の結果を結合する(Union)。Unionモジュールの接続端子を5個全部使ったのは今回が初めて。
- タイトルが取得できなかったアイテムを削除する(Filter)。「descriptionに何か入っている(/^.+$/にマッチする)アイテムだけ通過」という指定。
- 終わり(Pipe Output)
なかなか巨大なPipeになってしまった。一番大変だったのは、ケーブルがからまないようにモジュールを配置することです。あとスクリーンショットを取るのもかなり大変だった。
正直言って、マウスでドラッグしながら作るメリットは十分わかったので、もういい。あとは何かの言語で書きたい。GUIはとっつきやすいのは良いけど、慣れてくるといちいち大変すぎる。頭に浮かんだアイディアを形にするのに時間がかかりすぎる。言語で書けるようにしたところでYahoo! Pipesの存在価値が無くなるとは思えないけど。
ところでこんなPipeを作ったのは、もちろん自分が欲しかったからです。近いうちにこれ使って何か作ります。
- この記事のURI:
- http://muumoo.jp/news/2007/12/16/0pagetitle.html