2007年05月22日

BOOKLOG アイテム取得 API for JSONP このエントリーをはてなブックマークに追加

こんにちは、町亞聖です(嘘です)。

前回作成した BOOKLOG ASIN No 取得 for JSONP では、ブクログのユーザを指定して、そのASIN Noを取得するだけであった。「普通、アイテム名とか取得するだろ?」と思いつつも、何故そうしなかったかといえば、よくわかんなかったのである・・・orz
で、いろいろ試行錯誤すると(無理矢理)アイテム名を取得する方法が分かったので早速実装するのである。

下記を利用すれば、特定のブクログユーザの本棚にあるアイテムのASIN Noとアイテム名をJSON(P)形式で取得できるっす。更に、文字コードも指定できるよーなAPIを作ってみたっす。

で、以下、その説明。
BOOKLOG アイテム取得 API for JSONP
end point URL:
http://www.usamimi.info/~ryouchi/booklog/titlelink.php
パラメータ:callback:
コールバック関数名を指定
パラメータ:user:
一覧を取得したいユーザ名を指定
パラメータ:encode:
文字コードを指定する。指定できる文字コードは、UTF-8,SJIS,EUC-JPの3つ。(指定しなければUTF-8になる)


使い方:
・コールバック関数:viewasinno()
・encode:SJIS
・user:ryouchi
の場合、
http://www.usamimi.info/~ryouchi/booklog/titlelink.php?callback=viewasinno&encode=SJIS&user=ryouchi

などと指定する。


取得データ(サンプル)
viewasinno([{"asin":"4883924998" , "title":"\u795e\u69d8\u65e5\u8a18\u2015\u50d5\u306e\u7cbe\u795e\u75c5\u9662\u9a12\u52d5\u8a18"} ,
{"asin":"4916199626" , "title":"\u672c\u683c\u63a8\u7406\u59d4\u54e1\u4f1a"} ,
{"asin":"4812420881" , "title":"\u30c8\u30a5\u30eb\u30fc\u30fb\u30b3\u30fc\u30ea\u30f3\u30b0\u3008VOL.1\u3009"} ,
{"asin":"4104738026" , "title":"\u306f\u3044\u3001\u6cf3\u3052\u307e\u305b\u3093"} ,
{"asin":"4061823175" , "title":"\u88ab\u5bb3\u8005\u306f\u8ab0?"} ,
{"asin":"434400759X" , "title":"\u534a\u5cf6\u3092\u51fa\u3088 (\u4e0a)"} ,
{"asin":"4344007603" , "title":"\u534a\u5cf6\u3092\u51fa\u3088 (\u4e0b)"} ,
{"asin":"4763005014" , "title":"\u30b9\u30ce\u30fc\u30c9\u30fc\u30e0"} ,
{"asin":"408747402X" , "title":"\u5149\u3068\u5f71\u306e\u8a98\u60d1"} ,
{"asin":"4198506612" , "title":"\u6e9d\u9f20"} ,
{"asin":"4101448248" , "title":"\u672c\u306e\u96d1\u8a8c\u8840\u98a8\u9332"} ,
{"asin":"4894569116" , "title":"\u30a8\u30ea\u30fb\u30a8\u30ea"} ,
{"asin":"4101270228" , "title":"\u5947\u8de1\u306e\u4eba"} ,
{"asin":"4198922330" , "title":"\u9854"} ,
{"asin":"4167659018" , "title":"\u9670\u306e\u5b63\u7bc0"} ,
{"asin":"4062734567" , "title":"\u9b3c\u6d41\u6bba\u751f\u796d"} ,
{"asin":"4061821466" , "title":"\u30e9\u30b0\u30ca\u30ed\u30af\u6d1e\u2015\u300c\u3042\u304b\u305a\u306e\u6249\u300d\u7814\u7a76\u4f1a \u5f71\u90ce\u6cbc\u3078"} ,
{"asin":"4061821105" , "title":"\u30ab\u30ec\u30a4\u30c9\u30b9\u30b3\u30fc\u30d7\u5cf6\u2015\u300a\u3042\u304b\u305a\u306e\u6249\u300b\u7814\u7a76\u4f1a\u7af9\u53d6\u5cf6\u3078"} ,
{"asin":"4062734931" , "title":"\u4ea1\u56fd\u306e\u30a4\u30fc\u30b8\u30b9 \u4e0a \u8b1b\u8ac7\u793e\u6587\u5eab \u3075 59-2"} ,
{"asin":"406273494X" , "title":"\u4ea1\u56fd\u306e\u30a4\u30fc\u30b8\u30b9 \u4e0b \u8b1b\u8ac7\u793e\u6587\u5eab \u3075 59-3"} ,
{"asin":"4396631340" , "title":"\u30c7\u30a3\u30fc\u30eb\u30fb\u30e1\u30a4\u30ab\u30fc"} ,
{"asin":"4163220909" , "title":"\u30af\u30e9\u30a4\u30de\u30fc\u30ba\u30fb\u30cf\u30a4"} ,
{"asin":"4044295042" , "title":"Add\u2015\u6a5f\u68b0\u4ed5\u639b\u3051\u306e\u30db\u30e0\u30f3\u30af\u30eb\u30b9"} ,
{"asin":"4062649020" , "title":"\u30a6\u30e9\u30f3\u30d0\u30fc\u30ca\u306e\u68ee"} ,
{"asin":"4344403460" , "title":"\u865a\u8c8c\u3008\u4e0b\u3009"} ,
{"asin":"4344403452" , "title":"\u865a\u8c8c\u3008\u4e0a\u3009"} ,
{"asin":"416320900X" , "title":"\u30a4\u30f3\u30fb\u30b6\u30fb\u30d7\u30fc\u30eb"} ,
{"asin":"4043463022" , "title":"\u30d7\u30eb\u30c8\u30cb\u30a6\u30e0\u3068\u534a\u6708"} ,
{"asin":"4043541015" , "title":"\u5929\u4f7f\u306e\u5c4d"} ,
{"asin":"4104722014" , "title":"\u30e9\u30b9\u30fb\u30de\u30f3\u30c1\u30e3\u30b9\u901a\u4fe1"} ,
{"asin":"4575234990" , "title":"\u72af\u4eba\u306b\u544a\u3050"} ,
{"asin":"4396207557" , "title":"\u967d\u6c17\u306a\u30ae\u30e3\u30f3\u30b0\u304c\u5730\u7403\u3092\u56de\u3059"} ,
{"asin":"4163228705" , "title":"\u7a7a\u4e2d\u30d6\u30e9\u30f3\u30b3"} ,
{"asin":"4101448175" , "title":"\u3055\u3089\u3070\u56fd\u5206\u5bfa\u66f8\u5e97\u306e\u30aa\u30d0\u30d0"} ,
{"asin":"4061820834" , "title":"\u30c9\u30c3\u30da\u30eb\u30b2\u30f3\u30ac\u30fc\u5bae\u2015\u3042\u304b\u305a\u306e\u300e\u6249\u300f\u7814\u7a76\u4f1a\u6d41\u6c37\u9928\u3078"} ,
{"asin":"4344402685" , "title":"\u7121\u9593\u5730\u7344 \u4e0b \u5e7b\u51ac\u820e\u6587\u5eab \u3057 13-2"} ,
{"asin":"4344402677" , "title":"\u7121\u9593\u5730\u7344 \u4e0a \u5e7b\u51ac\u820e\u6587\u5eab \u3057 13-1"} ,
{"asin":"4797495588" , "title":"\u3061\u30fc\u3061\u3083\u3093\u306f\u60a0\u4e45\u306e\u5411\u3053\u3046"} ,
{"asin":"4344405455" , "title":"\u4f5c\u5bb6\u5c0f\u8aac"} ,
{"asin":"4488449018" , "title":"\u6a21\u5023\u306e\u6bba\u610f"} ,
{"asin":"4048734504" , "title":"\u5fd8\u308c\u96ea"} ,
{"asin":"408747349X" , "title":"R.P.G."} ,
{"asin":"434440551X" , "title":"\u706b\u306e\u7c89"} ,
{"asin":"4758430594" , "title":"\u9b54\u795e(\u307e\u304c\u307f)"} ,
{"asin":"4167642034" , "title":"\u30b2\u30eb\u30de\u30cb\u30a6\u30e0\u306e\u591c\u2015\u738b\u56fd\u8a18\u30081\u3009"} ,
{"asin":"4035401900" , "title":"\u6e80\u6708\u306e\u591c \u53e4\u6c60\u3067"} ,
{"asin":"4087472175" , "title":"\u5d29\u308c\u308b\u2015\u7d50\u5a5a\u306b\u307e\u3064\u308f\u308b\u516b\u3064\u306e\u98a8\u666f"} ,
{"asin":"434440324X" , "title":"\u8ee2\u751f"} ,
{"asin":"4894563878" , "title":"\u30a8\u30b9\u30d1\u30a4"} ,
{"asin":"4062648121" , "title":"\u4fee\u7f85\u306e\u7d42\u308f\u308a"} ,
{"asin":"4396326378" , "title":"\u7b11\u3046\u5c71\u5d0e"} ,
{"asin":"4488414028" , "title":"\u5b64\u5cf6\u30d1\u30ba\u30eb"} ,
{"asin":"4051029069" , "title":"\u661f\u304b\u3089\u304d\u305f\u5c11\u5973"} ,
{"asin":"4796643796" , "title":"\u5225\u518a\u5b9d\u5cf6\u300c\u8cab\u4e95\u5fb3\u90ce \u75c7\u5019\u7fa4\u300d"} ,
{"asin":"4101058210" , "title":"\u30ad\u30c3\u30c9\u30ca\u30c3\u30d7\u30fb\u30c4\u30a2\u30fc"} ,
{"asin":"4043461011" , "title":"\u4e8c\u91cd\u87ba\u65cb\u306e\u60aa\u9b54 (\u4e0a)"} ,
{"asin":"404346102X" , "title":"\u4e8c\u91cd\u87ba\u65cb\u306e\u60aa\u9b54 (\u4e0b)"} ,
{"asin":"4104616028" , "title":"GMO(\u4e0b)"} ,
{"asin":"410461601X" , "title":"GMO(\u4e0a)"} ,
{"asin":"4758410216" , "title":"\u706b\u661f\u30c0\u30fc\u30af\u30fb\u30d0\u30e9\u30fc\u30c9"} ,
{"asin":"448841401X" , "title":"\u6708\u5149\u30b2\u30fc\u30e0"} ,
{"asin":"4575711950" , "title":"8\u6642\u3060\u30e7!\u5168\u54e1\u96c6\u5408\u4f1d\u8aac"} ,
{"asin":"4062738279" , "title":"\u5ddd\u306e\u6df1\u3055\u306f"} ,
{"asin":"4334923755" , "title":"\u30b2\u30fc\u30e0\u306e\u540d\u306f\u8a98\u62d0"} ,
{"asin":"4059000345" , "title":"\u90aa\u8996\u2015\u6771\u4eac\u30b4\u30fc\u30b9\u30c8\u30b9\u30c8\u30fc\u30ea\u30fc"} ,
{"asin":"4062739682" , "title":"\u90aa\u9b54\u3008\u4e0b\u3009"} ,
{"asin":"4062739674" , "title":"\u90aa\u9b54\u3008\u4e0a\u3009"} ,
{"asin":"4062736691" , "title":"\u5618\u3092\u3082\u3046\u3072\u3068\u3064\u3060\u3051"} ,
{"asin":"4344004809" , "title":"\u9280\u884c\u7c60\u57ce"} ,
{"asin":"4796638113" , "title":"\u30d1\u30fc\u30d5\u30a7\u30af\u30c8\u30fb\u30d7\u30e9\u30f3"} ,
{"asin":"4062680130" , "title":"\u5931\u308f\u308c\u305f\u4e16\u754c \u75db\u5feb\u4e16\u754c\u306e\u5192\u967a\u6587\u5b66 (13)"} ,
{"asin":"416768201X" , "title":"\u795e\u306e\u3075\u305f\u3064\u306e\u8c8c"} ,
{"asin":"434440307X" , "title":"\u7761\u9b54"} ,
{"asin":"4062680157" , "title":"\u30e2\u30f3\u30c6\u30fb\u30af\u30ea\u30b9\u30c8\u4f2f \u75db\u5feb\u4e16\u754c\u306e\u5192\u967a\u6587\u5b66 (15)"} ,
{"asin":"4198915938" , "title":"\u7d2b\u82d1"} ,
{"asin":"4041304024" , "title":"\u60aa\u9b54\u306e\u624b\u6bec\u5504"} ,
{"asin":"4061817906" , "title":"\u5730\u7344\u306e\u5947\u8853\u5e2b"} ,
{"asin":"4041898048" , "title":"\u30d6\u30eb\u30fc\u30b9"} ,
{"asin":"4198613192" , "title":"\u30ab\u30ea\u30b9\u30de (\u4e0a)"} ,
{"asin":"4198613206" , "title":"\u30ab\u30ea\u30b9\u30de (\u4e0b)"} ,
{"asin":"4488416012" , "title":"\u751f\u3051\u308b\u5c4d\u306e\u6b7b"} ,
{"asin":"410443101X" , "title":"\u305d\u3057\u3066\u7c9b\u6e05\u306e\u6249\u3092"} ,
{"asin":"4763004204" , "title":"\u30c1\u30e7\u30b3\u30ec\u30fc\u30c8\u30fb\u30a2\u30f3\u30c0\u30fc\u30b0\u30e9\u30a6\u30f3\u30c9"} ,
{"asin":"4041789796" , "title":"\u59c9\u59b9\u2015Two Sisters"} ,
{"asin":"4106027674" , "title":"\u30aa\u30fc\u30c7\u30e5\u30dc\u30f3\u306e\u7948\u308a"} ,
{"asin":"4062092980" , "title":"\u6700\u60aa"} ,
{"asin":"4488425011" , "title":"\u615f\u54ed"}]);

このAPIを利用して簡単なデモを作ってみた。



BOOKLOG ユーザ名を入力しボタンを押すと、テキストボックスの中身を取得し、「BOOKLOG ASIN No 取得 for JSONP」に渡すパラメータを作成する。

下記のよーに使うとよいかも。(っていうか、この使い方しかできない?)

// アソシエイトIDを設定
var aid = "ryouchih-22";
function getasinno(){
  // divタグ内をクリア開始
  // prototype.jsを利用しています
  $(list).innerHTML ="";
  $(ruri).innerHTML ="";
  $(buri).innerHTML ="";
  // divタグ内をクリア終了
  // id=userの値を取得
  $user = document.getElementById('user').value;
  // jsonp取得用のURL作成
  // 下記のような形式で送る
  requesturl = "http://www.usamimi.info/~ryouchi/booklog/titlelink.php";
  requesturl += "?callback=viewasinno&encode=SJIS&user="+escape($user);
  // 取得したjsonpデータは外部スクリプトを埋め込むのと同様に利用可能
  // scriptタグ作成
  var script = document.createElement('script');
  script.src = requesturl;
  script.type = 'text/javascript';
  // scriptタグ append
  document.body.appendChild(script);
  // BOOKLOGユーザの本棚へのリンクを作成
  $(buri).innerHTML = '<a href = "http://booklog.jp/users/' + $user + '" target = "_blank">' + $user + 'さんの本棚</a>';
  // データの内容を見てみるためのリンクを作成
  $(ruri).innerHTML = '<a href = "' + requesturl + '" target="_blank">' + requesturl + '</a>';
}
function viewasinno(obj) {
  // objにはjsonpのデータが格納されている。
  // アイテム表示用HTMLの変数(resultData)を初期化
  var resultData="";
  // objのアイテムの数だけ繰り返す
  for(var i=0; i<obj.length; i++){
    // i番目の ASIN code は obj[i].asin で取得
    var iCode = obj[i].asin;
    // i番目のアイテム名(title) は obj[i].title で取得
    var title = obj[i].title;
    // ASIN code とアイテム名からamazonへのリンクを作成
    resultData += "<a href = 'http://www.amazon.co.jp/exec/obidos/ASIN/" + iCode + "/" + aid + "/ref=nosim/' target = '_blank'>" + title + "</a><br />";
  }
  // resultData を id=list の divタグ内に表示
  $(list).innerHTML = resultData;
}



例えばこんな風なこともできるであろう。

このAPIを使えばブクログの登録データを Javascript を使ってこのように加工できるのでちょいと便利と思われるっす。
このAPIはどーやって動いているかというと、特定のサイトをスクレイピングという手法を使ってパラメータを抜き出しているのである。
スクレイピングとは、Web APIを作成するひとつの手法で、ある決まったフォーマットに基づいて作成されたWebサイトはその構造も(殆ど)同じ構造であることに着目し、HTMLを正規表現などで解析し、必要部分(今回の場合はASINナンバーとアイテム名)を抜き出し、サーバ側で加工し、利用しやすい形式(今回の場合はJSONP形式)で再提供する手法のことをいうらしい。
今回解析対象としたサイトは りょーちの本棚 : Booklog(リストビュー) をスクレイピングしているっす。
上記サイトのHTMLを見ると、下記のよーな文がある。
<a href="/asin/4104738026/via=ryouchi" class="list_books_title" title="はい、泳げません">

先ずHTMLファイルを取得し、 <a> タグの href 属性の中で、/asin/の文字があるところだけを抜き出して見る。これを利用して、ASINコードを取得する。
次に title 属性を抜き出してタイトルを取得する。
ASIN と title を配列に入れ、PEAR :: PEPr :: Details :: Services_JSON でJSON(p)形式に加工するのである。
Services_JSONについての日本語の解説は下記を参考にしたっす。
また、APIの解析にはphpのtidy関数を利用しているっす。
で、どーでもよいが、tidy関数の文字コードのエンコードの指定と mb_convert_encoding() の文字コードの指定のパラメータが異なるのに気づくのにちょいと時間が掛かってハマったっす。(何故同じにしないのか・・・)

なお、無理矢理作った感があるが、ブクログのトップページには、「New Booklog Coming Soon..」の文字が・・・
うーむ。スクレイピング処理をしているので、HTMLの構造が変わると動かなくなるっす・・・(ダメばい)。

つーか、こんなの作らなくでも イエイリ先生 が、きっときちんとしたAPIを提供してくれるに違いないっす(謎)。

なお、JSONP だと JavaScript の XMLhttpRequest() 関数を利用しなくても、
<script type="text/javascript" src"=http://・・・・"></script>
のよーに読み込むような感じでオブジェクトとして直ぐに使えるってのが便利かも。
クロスドメインによりアクセスが制限されている場合などはこんな感じでやればよかろう。今後APIの提供もJSONP形式で提供されることが多くなるよーな予感がするっす。
(といっても、実際はJSONもJSONPもまだ今ひとつよくわかってないっす・・・orz)
(って、このフレーズはまたもや前回の記事のコピペでした)
posted by りょーち | Comment(2) | TrackBack(0) | Web周辺技術
この記事へのコメント
すげえ!
でもでも、近々リニューアルしちゃうのでhtmlは変わっちゃうかもです、、その際には再度ご連絡します!

本当にありがとうございます。
Posted by ieiri at 2007年05月27日 03:07
ieiriさま、こんにちは。りょーちと申します。こんな辺境の地までお越しいただきまして恐縮です。

作った後に「これはもしかして勝手なことしたら怒られるのかも」と思い、小心者なので、ieiriさんのBLOGにお邪魔し、コメントを残させていただきました。
リニューアル、楽しみにしています。
ご多忙かと存じますが、頑張ってください。影ながら応援しております。

ではでは。
Posted by りょーち at 2007年05月28日 14:18
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: