t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

amazonアソシエイトのウィジェットがChromeで自動再生されなくなったのでランダムに商品を並べる機能をJavaScriptで自作する。

このブログはamazonアソシエイトに参加しており、その広告収益を運営費に充てている。
先日までこのブログのサイドバーにはA8.netの固定バナーを表示していたが、まったく収益になってなかったので、そちらを削除して空いたスペースにおススメの小説を掲載することにした。

当初はamazonのスライドショーウィジェットが良さげだったのでそれを使う予定だったのだが、配置してみたところ自動再生されない。
調べたところ、去年の9月のアップデートで、Google Chromeでは重要でないFlash(つまり広告)は自動再生されない仕様になったとのこと。
www.itmedia.co.jp

広告というのは勝手に目に飛び込んでくるから興味を引くのであって、わざわざクリックして再生してくれるユーザーはほとんど居ない。
それでスライドショーウィジェットを使う案はボツ。

Flashを使わないお気に入りウィジェットというのも試してみたけれど、どうも商品画像が小さすぎて興味をそそられない。
「これ欲しい」とか、「これ面白そう」というのは直感的なもので、小っちゃい文字と小っちゃい画像ではインパクトに欠ける。
やはりバーンと画像で魅せないと。

やりたいことは、自分のおススメの小説をランダムに3つくらい、大きめの画像で表示させること。
ということで、JavaScriptで自作することにした。

まず、amazonアソシエイトの商品リンクで画像のみのサイズ中を選択し、URLを取得する。
すると、以下のようなURLが取得できる。

<a  href="https://www.amazon.co.jp/gp/product/B0093GE1UM/ref=as_li_tf_il?ie=UTF8&camp=247&creative=1211&creativeASIN=B0093GE1UM&linkCode=as2&tag=hogehoge"><img border="0" src="http://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B0093GE1UM&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=hogehoge" ></a><img src="http://ir-jp.amazon-adsystem.com/e/ir?t=hogehoge&l=as2&o=9&a=B0093GE1UM" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

このうち、可変項目は、商品コード「B0093GE1UM」と自分のID「hogehoge」なので、そこだけ変数にしてループで回せば別の商品を次々に表示できる。
また、おススメ商品群から3つピックアップしたかったので、配列からランダムでピックアップする処理にした。

サイドバーのモジュールに埋め込んだコードは以下のとおり。

<p>オススメ!松岡 圭祐 Kindle本</p>
<div id="amazon_km_kindle" style="margin-left:20px;">
</div>
<script type="text/javascript"><!--
window.onload = function(){
	var asins = [ "B009GPMSN2", "B0093GE1UM", "B009VZ8L5G", "B00QJDTG2K", "B016KDOC36" ] ;
	var associate_id = "hogehoge";
	var display_number = 3;
	for(var i = 0; i < display_number; i++) {
	    var a = Math.floor( Math.random() * asins.length )
	    var asin = asins.splice(a,1);

	    var anchor = document.createElement("a");
	    anchor.href = "https://www.amazon.co.jp/gp/product/" + asin
	    	+ "/ref=as_li_tf_il?ie=UTF8&camp=247&creative=1211&creativeASIN=" + asin
	    	+ "&linkCode=as2&tag=" + associate_id;
	    
		var img1 = document.createElement("img");
		img1.src = "http://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=" + asin
			+ "&Format=_SL160_&ID=AsinImage&MarketPlace=JP"
			+ "&ServiceVersion=20070822&WS=1&tag=" + associate_id;
		img1.border = "0";
		
		anchor.appendChild(img1)
		
		var img2 = document.createElement("img");
		img2.src = "http://ir-jp.amazon-adsystem.com/e/ir?t=" + associate_id + "&l=as2&o=9&a=" + asin;
		img2.width = "1";
		img2.height = "1";
		img2.border = "0";
		img2.alt = "";
		img2.style = "border:none !important; margin:0px !important;";

	    var div = document.getElementById("amazon_km_kindle");
	    div.appendChild(anchor);
	    div.appendChild(img2);
	}
}
// --></script>

JavaScriptで配列と呼ばれるものは、実はリスト構造になっているようで、データの切り出しや挿入用の命令が用意されている。
VBAやCを経験した人からするとリスト構造を配列と呼ぶのは違和感があるかもしれない。

【参考:VBAの場合、配列はそのまま配列構造】
thom.hateblo.jp

JavaScriptの配列は非常に多機能で使い勝手がよく、pushやpopでスタックのような操作ができたり、spliceでデータの一部を切り出したり、joinで文字列結合させたりできる。

さて、このブログの読者はVBA使いがメインだと思うので、前述のJavaScriptのうち、商品群からランダムに3つピックアップする処理について、VBAでもやってみようと思う。
VBAで書くと、こうなる。

Sub 束からランダムに3つピックアップ()
    '配列を準備
    Dim asinArray()
    asinArray = Array("B009GPMSN2", "B0093GE1UM", "B009VZ8L5G", "B00QJDTG2K", "B016KDOC36")
    
    'コレクションに格納
    Dim asinCollection As New Collection
    Dim asinCode
    For Each asinCode In asinArray
        asinCollection.Add asinCode
    Next
    
    'ランダムにピックアップ
    Dim i, n
    For i = 1 To 3
        n = Int((asinCollection.Count) * Rnd + 1)
        Debug.Print asinCollection(n)
        asinCollection.Remove n     '同じコードを取らないように取り除く
    Next
End Sub

JavaScriptの場合は配列がリスト構造なので扱いやすいが、VBAの場合は一旦操作しやすいCollectionに格納する。
JavaScriptの配列はspliceメソッドで値を取出しつつ、配列から取り除くことができるが、VBAのCollectionの場合は別途Removeが必要となる。

束から重複なくランダムにピックアップする処理はいろいろと応用が利く。
たとえば、全て取り出して別のコレクションにAddすればコレクションのシャッフルができる。
あるいは問題集からランダムな30問を表示させることもできる。

言語が変わってもこうしたアルゴリズムは潰しが利くので覚えておくとよいと思う。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。