| @技術/プログラミング
自作の Lokka プラグインに Amazon の Product Advertising API に問い合わせてアフィリエイトリンク付きの商品画像を返すやつがある。 Amazon 上の商品管理...

糸島の海

自作の Lokka プラグインに Amazon の Product Advertising API に問い合わせてアフィリエイトリンク付きの商品画像を返すやつがある。 Amazon 上の商品管理番号を <!-- ASIN=XXXXXXXX --> みたいな感じで本文中に書いとくと良い感じに小銭を稼げるかたちのリンクにして画像を表示してくれるという便利なやつ。

Amazon の規約上、 Amazon Product Advertising API に対しては一秒間に一リクエストしか送ってはいけないことになってるので、データを取得する度に 1 秒 sleep するようにしていたけど、一ページ内で複数のリンクがあるときにキャッシュがエクスパイアして Amazon の API を叩くとめっちゃレスポンス遅くなってださかったので非同期で取るようにした。ページコンテンツ本体はサクッと返して、商品情報などの取得はページがレンダリングされたあとに JavaScript で行う。 Amazon から JSON を取ってくる処理自体は Ruby にやらせる。

+----------+            +----------------+             +--------------------------------+
|          | +--------> |                | +---------> |                                |
|  client  |            |  Ruby (Lokka)  |             | Amazon Product Advertising API |
|          | <--------+ |                | <---------+ |                                |
+----------+            +----------------+             +--------------------------------+

最初は雑に body の innerHTML を正規表現で replace したりしてたんだけど、そうすると Twitter のウィジェットなど本文内に埋め込んである script タグが動かなくなる問題に気がついた。 HTML 5 の仕様で、 innerHTML = で挿入されたコンテンツの script タグは無視されるらしい。なるほど〜。

element.innerHTML

element.innerHTML

Element オブジェクトの innerHTML プロパティは、要素内の HTML または XML のマークアップを取得したり設定したりします。

developer.mozilla.org

ということでもうちょい調べたら DOM には Node.nodeType というプロパティがあって、COMMENT_NODE など type を持っているらしい。

Node.nodeType

Node.nodeType

ノードの種類を表す整数のコードを返します。

developer.mozilla.org

<!-- ASIN=XXXXXXXX -->COMMENT_NODE として扱われるので、こいつの後ろに document.createElementして JavaScript で動的に生成された要素を突っ込むようにした。 Promise を使ってナウでヤングな感じに書いた。

let promise = new Promise(function(resolve, reject) {
  request.open('GET', url);
  request.onreadystatechange = function() {
    if (request.readyState != 4) {
      // リクエスト中
    } else if (request.status != 200) {
      // 失敗
      reject(request.response);
    } else {
      // 取得成功
      let formatter = new Formatter(request.response);
      let result = formatter.formatItem();
      resolve(result);
    }
  };
  request.send();
});
promise.then(function(result) {
  let previous = node.previousSibling;
  let parent = node.parentNode;
  let d = document.createElement('div');
  d.className = 'amazon';
  d.innerHTML = result;
  parent.insertBefore(d, previous.nextSibling);
}).catch(function(error) {
  console.log(error);
});
return promise;

意地でも jQuery 使うまいと思ってやってみたけど意外と大丈夫だった。楽をせずに素の JavaScript を書いていると精神が浄化されるような感覚があってよい。写経に通じるものがある。写経やったことないけど。

この記事に似ている記事

  • Screenshot
    最近、”Product Advertising API PHP4” みたいなキーワードで検索してくる人が多いです。みなさん対応にてんやわんやのようですね。ちょっとググったところ、レンタルサーバーでPHPのバージョンが4の場合、HMACエンコー...
  • Screenshot
    Google Readerみたく、iPhoneでアクセスしたときにJavaScriptで画像を縮小表示させるようにしてみた。当然ながら自サーバーにあるものだけでなく、Flickrとかの画像も縮小表示する。そしてこれまた当然ながら画像をリサイズ...
  • Screenshot
    一個前のやつ、セルフ添削してみました。if (imgWidth &gt; imgHeight) のところで True でも False でも同じ処理になってて無意味だったし、i を初期化してなかったし全然ダメダメですね。userAgent っ...
  • Screenshot
    最近のコメントのページ(Recent Comments)で、各コメントのタイトルにマウスオーバーするとコメントの本文を取ってきてぬるっと表示するようにした。Tumblrの notes を読み込むときみたいなアクション。結構かっこいい。コードは...
  • Screenshot
    ポータルシットのコメント一覧ページで、マウスオーバーして全文を取得するやつをかっこよくした。これまではjQueryでスクレイピングして、記事のパーマリンクからコメントを取得していた。しかしこれは無駄なクエリが発生する。記事本文を取得するクエリ...
  • Screenshot
    Pinboard にブックマークしたらはてなブックマークに同期するやつを作った。 morygonzalez/pinboard2hatena Sync はてなブックマーク with P...

Comments


(Option)

(Option)