JavaとAmazonProductAdvertisingAPI, CurrencyAPIで世界各国のAmazonの商品価格比較ツール作ってみた(2017/01/29)

# hello world!
### 自己紹介
はじめましてalpacatomと申します。M1の院生です。
やっと論文の佳境を超えて、少しばかり時間が出来たので、貴重な土日を犠牲に初投稿させて頂きます。
新参者ゆえ、どうぞ温かく見守ってください。改善案や意見などして頂けると助かります。
今回は、Amazon Product Advertising APIとCurrency APIを使って、6カ国のAmazonでの商品の価格を比較するツールを作りました。もちろん送料込みです。

>Note: 使えるようになるまでの準備が相当面倒くさいので、覚悟しておいてください。

### 動機 (アイスブレイク)
「みんな大好き『ビッグバン★セオリー』のBlu-rayディスクが欲しい」 → 「でも(院生は)お金がない」 → 「あれ！？日本より米国Amazonの方が安くね?」 ← 今ココ
と至り、結果よく分からなかった上、国ごとのAmazonでの値段が違うことを知ったので作りました。
>Tips: __[ビッグバン★セオリー](http://www.superdramatv.com/line/bigbang/)__とは?
超面白い海外コメディドラマ。研究者を目指している人もそうでない人にもオススメ出来る作品で、特に院生の方は__必見__です。
ちなみに私はSeason1-6まで二週しました。(Netflix最高！)

あと後々には、_Superdry(極度乾燥)しなさい_ のバッグの購入を考えている...などが主な動機です。
>参考: [Superdry (極度乾燥)しなさい](http://banqmosh.com/superdry)


##Currency API
本題に入ります。
為替レートの情報を得るためのAPIで、登録すれば使えるようになります。
今回はFreeのものを使用しています。
https://currencylayer.com/
ここでCurrencylayerのAPIキーを取得します。

##Amazon Product Advertising API
以下の記事を参考にさせて頂きました。
- http://qiita.com/someone7140/items/df3514b3d139c1b94ef9
- https://www.panzee.biz/archives/6222
なので、このセクションの作業をする場合には参考にすると捗ります。

###Amazonアソシエイトタグ
ここが正念場です。
比較したい国の登録を済ませ、Associateタグを手に入れます。(今回は日本をベースとしているので、日本は必須です。)
StackOverflowのとある記事によりますと、各国で登録しないと使えない的なことが投稿されていたため、必要な国"全部"で登録します。
- https://affiliate-program.amazon.com/
- https://associates.amazon.ca/
- https://affiliate-program.amazon.co.uk/
- https://partnernet.amazon.de/
- https://partenaires.amazon.fr/ 
- https://affiliate.amazon.co.jp/

###AWSアクセスキーとシークレットキー
- 上記サイトの説明を読みつつアクセスキーとシークレットキーを取得する。
色々試しましたが、何故か日本のキーだけ別にしないと動かなかった(むしろ2つだけで動く)ので、日本とそれ以外の二つ取得しました。
これで準備完了です。

##使い方
Eclipseで開発したので、Eclipseを使っている方はGithub (https://github.com/alpacatom/ComparingPrices-via-AmazonAPI) から引っ張ってきたプロジェクトをimportし、上記で取得した鍵を(Currency.javaとSearchAnItem.javaにて)設定すれば使えます。
検索には、必要なパラメータがいくつかあります。
- ASIN番号 (参考 https://www.amazon.com/gp/help/customer/display.html?nodeId=200202190#find_asins)
- 重さ(kg) (重さによって海外からの発送料が変わるため、デフォルトは1kg以下)
- 探したい品物のジャンル(例. BooksやDVDなど。詳しくはShipmentCharge-*.txtの1列目を参考にしてください。)
が必要になります。

##mainクラス
以下にmain関数だけ載せます。流れとしてはCSVファイルから送料表を引っ張り、CurrencyAPIとAmazonAPIを叩いて為替レートと商品情報の価格を取得します。
詳しくはGithub (https://github.com/alpacatom/ComparingPrices-via-AmazonAPI) にて

```java:AmazonAPI.java
	public static void main(String[] args) {
		// Initializing
		ItemData arr[] = new ItemData[ItemData.COUNTRY_NUM];
		for(int i=0;i<ItemData.COUNTRY_NUM;i++){
			arr[i] = new ItemData();
		}
		String line[] = new String[ShipmentCharge.CSV_MAX_LINE_SIZE];
		ShipmentCharge SC[][] = new ShipmentCharge[ItemData.COUNTRY_NUM][ShipmentCharge.CSV_MAX_LINE_SIZE];
		// Get Shipment Charges
		for(int j=0;j<ItemData.COUNTRY_NUM;j++){
			line = ItemData.ReadFile(ShipmentCharge.ShipmentTXT[j]);
			String stmp[] = new String[ShipmentCharge.CSV_MAX_COLUM_SIZE];
			int k=0;
			while(line[k]!=null){
				stmp = MyParser.parseCSV(line[k]);
				SC[j][k] = ShipmentCharge.MakeTable(SC[j][k], stmp, j);
				k++;
			}
		}
		// Calculate the lowest Shipment Charges each countires.
		Double[] dtmp = new Double[6];
		dtmp = ShipmentCharge.LowestCalcSC(SC,ItemData.category);
		// Get Currencies via currencylayer
        String json = Currency.GetCurrencies();
        Double CurrenciesRate[] = new Double[ItemData.COUNTRY_NUM];
        CurrenciesRate = MyParser.getCurrencies(json);
		// Get Price and Country via Amazon Product API
		String xml[] = new String[ItemData.COUNTRY_NUM];
		final String tag[] = {"CurrencyCode","FormattedPrice"};

		for(int i=0;i<ItemData.COUNTRY_NUM;i++){
			arr[i].setCountry(ItemData.Countries[i]);
			xml[i] = SearchAnItem.SearchByID(ItemData.getItemID(), i);
			arr[i].setShitpment(dtmp[i]);
			arr[i].setCurrenciesCode(MyParser.getTagElmFromXML(xml[i],tag[0]));
			arr[i].setPrice( MyParser.Convert2Double(MyParser.getTagElmFromXML(xml[i],tag[1])));
        	arr[i].setCurrenciesRate(CurrenciesRate[i]);
        	arr[i].PrintAll();
		}
	}
```

##実行結果
全部ひっくるめて計算した結果をUSDドルで表示します。なのでTOTAL:が低いほど"安い"ということを示しています。
以下がビッグバン★セオリーSeason1-9のBDの値段(送料込)です。お分かりいただけだたろうか、日本語不要(英語字幕は有)であれば 115*(Max-min) = 2990円ほど得するのである。
![ad1b905491ba78d3da57cbb32752f150.png](https://qiita-image-store.s3.amazonaws.com/0/153487/a685d994-7992-dd7f-54f8-e4b33f78e468.png)

##所感
ここまで読んでくださってありがとうございました、また何か作ったら投稿しようと思います。
###得たもの
- Eclipseの使い方 (今回はじめてだった)
- Javaのコーディング (講義以外で使ったことなかった)
- いろんなAPI・外部ライブラリに触れた (HTTPリクエストの送り方やJSONおよびXMLからの要素抽出など)
- 正規表現の使い方 (汚いけど初めて自分で作った)

###失ったもの
- 土日 (ここ重要)

###やり残したこと
- デバッグと例外処理はほぼやってません。(稀にHTTPリクエストを送るところでコケる? 時間があったら直したい。)
- 複数の品物の注文に対応させこと。 今回は単品注文しか想定しておらず、複数注文する場合の計算が変わるため
- URLからASIN番号を引っ張れるようにすること。いちいちASIN番号を探すのがめんどくさい。
- 特急便の送料も選択可能にすること。時間とお金間でコスパがいいところを選びたい需要があるかも
- ベースとなる国(現在は日本)も選択可能にすること。送料の規定が変わってしまったらまたやり直しなため。(値段を調べるのが面倒なので多分やりません。)

##参考文献
>Amazon Product API document
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Welcome.html
Currencylayer API document
https://currencylayer.com/documentation
ファイル入出力 
https://www.caveofprogramming.com/java/java-file-reading-and-writing-files-in-java.html
正規表現 
https://docs.oracle.com/javase/jp/6/api/java/util/regex/Pattern.html
http://qiita.com/ymsr5612/items/7c8811b5cf37d700adc4
Base64 エンコード/デコード (ここでEclipseにjarがimportできなくてハマった)
http://criticalbreak5.seesaa.net/article/420080828.html
XML via DOM(結局使ってない)
http://www.fireproject.jp/feature/xml/programing/java-dom.html
JSON 
http://www.task-notes.com/entry/20150919/1442639772