2012年9月11日

プログラミング

XMLのWebAPIを爆速で使いこなせるフレームワーク

  • このエントリーをはてなブックマークに追加

Yahoo!デベロッパーネットワークの中野(@Hiraku)です。先日、爆速JSONPを使うと、JSONPのWebAPIを簡単に使いこなせることを示しました。

とは言っても、JSONPに対応していないWebAPIも数多くあります。ニュースAPI知恵袋API…。これらは現時点ではXMLしか対応しておらず、爆速JSONPではブログパーツ化できません。

…いや、「ブログパーツ化できませんじゃなくて、とっととJSONPに対応しろよ」とお叱りを受けるところなんですが、実はXMLなら何でもJSONPに変換することのできる「YQL」というサービスがあり、これを使うことでカバーする方法があるのです!

YQLの説明は後にして、まずはデモをご覧ください。Yahoo!ニュースのトピックスAPIを埋め込みました。

どうでしょう。ちゃんと動いているでしょうか?(直近の更新によって記事数が増減するようです。)

ソースコードはこんな感じです。このソースコードを「news.html」などの名前で保存し、ダブルクリックしてブラウザーで開いて実行してみてください。 おっと、「APPLICATION_ID」の部分はデベロッパーネットワークで発行したアプリケーションIDに差し替えてから実行してくださいね。

<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Yahoo!ニュースAPIをブログパーツ化する</title>
 </head>
 <body>
  <h1>Yahoo!ニュースAPIをブログパーツ化するデモ</h1>

  <script src="https://s.yimg.jp/images/yjdn/js/bakusoku-yql-v1-min.js"
    data-url="http://news.yahooapis.jp/NewsWebService/V2/topics"
    data-p-category="computer"
    data-p-appid="APPLICATION_ID">

   <ul>
    {{#query.results.ResultSet.Result}}
     {{#Title}}
      <li><a href="{{Url}}">{{Title}}</a>
       <small>{{HeadlineUpdateTime}}</small><br>
       <b>{{TopicName}}</b>: {{Overview}}
      </li>
     {{/Title}}
    {{/query.results.ResultSet.Result}}
   </ul>

  </script>

 </body>
</html>

書かれているのはただのHTMLと、scriptタグ一つだけです。scriptタグの中身もHTMLのテンプレートであり、JavaScriptは一切記述していません。当然、「サーバーを準備してプロキシする」「XMLをJSONに変換する」などの作業も全く行っていません

にも関わらず、XMLのレスポンスを埋め込むことができました。

これで、「HTMLだけ書けばXMLのWebAPIを使いこなせる」ようになりました。

YQLとは

さて、もう少し解説していきます。冒頭で少し書きましたが、このJavaScriptフレームワークは裏側でYQLを利用しています。

YQLとは米Yahoo! Developer Networkが提供している、ありとあらゆるWeb上のリソースにアクセスすることができる開発者向けのサービスです。

文法はSQLのようで独特ですが、要約すると

  • XML、HTML、RSS、CSVなどをJSONPに変換
  • WebAPIレスポンスの加工
  • キャッシュ機能つき
  • 登録などをしなくても使える(利用制限等についてはYQL公式サイトをご参照ください)

こういった機能を持つ、汎用的なプロキシサービスです。

YQL自体を詳しく説明すると、それだけで数記事を費やすことになってしまうので、ここでは「YQLというものを使うと、XMLをJSONPに変換して扱えるようになる」という点だけご理解いただければ大丈夫です。

爆速JSONPから爆速YQLへ

爆速JSONPにYQLを組み合わせることも可能ではあるのですが、URLエスケープを手動でしなければならないなど、ちょっと使いにくくなってしまいます。

そこで少し手を加えて作った爆速JSONPの進化版フレームワーク、それがこの「爆速YQL」です。先ほど見ていただいた通り、scriptタグ一つでブログパーツを作ることができます。YQLを意識する必要もありません。

爆速の名を引き継ぐため、爆速JSONPとなるべく同じ書き方ができるようにしました。data-urlにはXMLを返すAPIのURLを書き、data-p-○○にパラメータを列挙していき、scriptタグの中身にHTMLテンプレートを書くだけです。

<!-- 爆速YQLの文法 -->
<script src="https://s.yimg.jp/images/yjdn/js/bakusoku-yql-v1-min.js"
  data-url="XMLを返すAPIのURL"
  data-p-パラメータ名1="APIに渡す値1"
  data-p-パラメータ名2="APIに渡す値2"
  data-p-パラメータ名3="APIに渡す値3"
...
>

(ここにmustacheテンプレートを書く)

</script>

これだけで、

  • data-urlとdata-p-○○属性からYQLのクエリを生成(SELECT * FROM xml WHERE url='...'を作成する)
  • YQLにクエリを送信
  • (YQLがWebAPIにリクエストを行い、レスポンスをJSONPに変換して返してくる)
  • レスポンスをMustacheテンプレートに当てはめる
  • 出来上がったHTMLをscriptタグと置き換える

という一連の動作をします。

テンプレート部分は爆速JSONPと同じくmustache.jsを使っていますので、文法は爆速JSONPの記事か、Mustacheの公式マニュアルを参照してください。

なお、爆速JSONPにあった「テンプレートを空っぽにしておくとデバッグモードになる」「data-filterでレスポンスの加工ができる」などの機能はそのまま引き継いでいて、同じように使うことができます。

高度な使い方

今まで見てきたような爆速JSONP互換の書き方とは別に、YQLのクエリを直接書いてリクエストすることも可能です。

生クエリを書きたい場合は、data-urlではなくdata-yqlという属性値を使ってください。

YQLの文法を理解する必要はありますが、生クエリの方がずっと高度なことができます。具体例をいくつか示してみます。

爆速YQLでRSSをページに埋め込む

爆速YQLはYQLをバックエンドに使っていますので、YQLがJSONPに変換できるものであれば何でもブログパーツ化可能です。適用例はWebAPIに限らないわけです。

例えば、YQLはfeedというテーブルを持っており、RSSやAtomをJSONPに変換する機能を持っています。これを使うと、ページ中にRSSリーダーを埋め込むことができます。

ためしにYahoo! JAPAN Tech BlogのAtomフィードを使って、直近の記事一覧を出してみます。

<script src="https://s.yimg.jp/images/yjdn/js/bakusoku-yql-v1-min.js"
  data-url="http://techblog.yahoo.co.jp/atom.xml"
  data-yqltable="feed">
<ul>
{{#query.results.entry}}
 <li><a href="{{link.0.href}}">{{title}}</a></li>
{{/query.results.entry}}
</ul>
</script>

data-urlにTechBlogのAtomフィードのURLを、data-yqltableにfeedを指定しただけですが、これでページに埋め込むことができました。単にRSSを表示するだけのブログパーツなら他にもありそうですが、爆速YQLならHTMLをフルカスタマイズできます。サイトのデザインに合わせて表示するのもやりやすいことでしょう。

なお、AtomフィードもXMLの一種であるため、data-yqltableを指定しなくても動作します。ただ、余分な要素が返ってきたりRSS1.0だとJSONへの変換時に情報が抜け落ちることがあったりするので、feedテーブルを指定する方がオススメです。

応用ですが、生クエリを直接書くとLIMIT句によって絞り込みができます。data-urlだとRSSにある全記事を表示してしまいますが、最新数件だけ必要なこともあるでしょう。

<script src="https://s.yimg.jp/images/yjdn/js/bakusoku-yql-v1-min.js"
  data-yql="SELECT * FROM feed
             WHERE url='http://techblog.yahoo.co.jp/atom.xml'
             LIMIT 3">
<ul>
{{#query.results.entry}}
 <li><a href="{{link.0.href}}">{{title}}</a></li>
{{/query.results.entry}}
</ul>
</script>

data-yqlに「LIMIT 3」を加えました。先ほどとテンプレート部分は変えていませんが、出力される記事の数が3件だけになるはずです。

爆速YQLでHTMLをスクレイピングしてブログパーツ化

他にも、htmlテーブルなんていうものもあり、あるWebページを読み取って、その特定の部分だけ抜き取ってページに埋め込むことも可能です。(著作権の問題があるので使い方には注意が必要ですが。) スクレイピングと呼ばれますね。

例えばYahoo!デベロッパーネットワークのサイトマップから、提供しているWebAPIの一覧を取得して表示するにはこんな感じになります。


<script src="https://s.yimg.jp/images/yjdn/js/bakusoku-yql-v1-min.js"
 data-yql="SELECT * FROM html
            WHERE url='http://developer.yahoo.co.jp/sitemap/'
              AND xpath='//div[@id=\'webapi\']//li'"
>
<ul>
{{#query.results.li}}
 <li style="float:left;width:100px;list-style-type:none;">
  <img src="{{p.0.a.img.src}}" alt="{{h4.a.content}}"><br>
  <a href="{{h4.a.href}}" style="font-size:small">{{h4.a.content}}</a>
 </li>
{{/query.results.li}}
</ul>
</script>

urlで取得したいHTMLのURLを指定し、xpathで抜き出したい部分を示すXPathを指定します。「'」(クオーテーション)のエスケープに注意してください。

htmlテーブルでは膨大な量のレスポンスが返ってくるので、data-yqlで生クエリを書いて、XPathを指定して絞り込むのがオススメです。

スクレイピングと言うと難しいプログラミングをしなければならないイメージがあるかもしれませんが、これなら大分楽なのではないでしょうか。

HTMLはWebAPIではありませんので構造が保証されておらず、サイトのデザインが変わったりすれば使えなくなってしまいますが、WebAPIされていない情報をサクッと抜き出すことができます。

たとえば、こんな使い方はどうでしょうか。

  • 自分で運営するWebサイトのメニュー部分だけメインページからスクレイピングし、他のページで埋め込んで使いまわす(一カ所メニューを更新すれば全ページで反映される!)

静的なHTMLしか配置できないホームページサービスはYahoo!ジオシティーズの無料版や、最近流行のGithub Pages(外部サイト)などたくさんあります。自サイトのスクレイピングやWebAPIの埋め込みを行えば、PHPやCGIを使わずともかなり高度なサイトが作れるでしょう。

まとめ

ということで、Yahoo!デベロッパーネットワークで公開されているWebAPIは全て、爆速JSONPもしくは爆速YQLでブログパーツ化できるようになりました。(ただしユーザー認証が必要なものを除く)

こんな風にWebAPIのレスポンスをただ単に表示するだけであれば、難しいプログラミングは必要ありません。PHPやPerlなどが動くレンタルサーバーも必要ありません。もっと気軽にWebAPIを使っていただくきっかけになれば、と思います。

爆速YQLの利用について

以下のURLを直接埋め込む形でご利用になれます。

今のところ、爆速JSONPと同じくご利用にはYahoo! JAPANのソフトウェアガイドラインに従ってください。

爆速JSONPと同じく、OSS化に向けて調整中ですので、ご期待ください。

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加