2014年5月10日

SaclaからAmazon APIにアクセス

準備

AWS Product Advertising API(いわゆるAmazon API)を叩くにあたり、
  • Access Key ID
  • Secret Access Key
  • Associate Tag
が必要になります。

Access Key ID と Secret Access Key の作成

https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html
の右側にある「アカウント作成」からアカウントを作成します。

https://console.aws.amazon.com/iam/home?#security_credential
の「Access Keys (Access Key ID and Secret Access Key)」項目を開いて、
[Create New Access Key]をクリックします。

Associate Tag の作成 

http://www.ajaxtower.jp/ecs/pre/index4.html
こちらのページに詳しいです。

コード

    val accessKey = /* Access Key ID */
    val secretAccessKey = /* Secret Access Key */
    val associateTag = /* Associate Tag */

    val df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

    val baseUrl = new URI("http://ecs.amazonaws.jp/onca/xml")
    val params = TreeMap(
      "Service"         -> "AWSECommerceService",
      "AWSAccessKeyId"  -> accessKey,
      "Version"         -> "2011-08-02",
      "Operation"       -> "ItemSearch",
      "SearchIndex"     -> "Books",
      "Keywords"        -> "よつばと",
      "Timestamp"       -> df.format(new Date()),
      "Sort"            -> "daterank",
      "ItemPage"        -> "1",
      "ResponseGroup"   -> "ItemAttributes,Images,BrowseNodes",
      "AssociateTag"    -> associateTag
    )

    def encodeUrl = URLEncoder.encode(_: String, "UTF-8").replace("+", "%20").replace("%7E", "~").replace("*", "%2A")

    val canonicalSb = new StringBuilder()
    params.foreach { case (k, v) =>
      canonicalSb.append("&").append(encodeUrl(k)).append("=").append(encodeUrl(v))
    }

    val canonicalStr = canonicalSb.substring(1)

    val strToSign = "GET\n" + baseUrl.getHost() + "\n" + baseUrl.getPath() + "\n" + canonicalStr

    // secretAccesKeyでstrTosignのHmac-SHA256ハッシュを作成
    val key = new SecretKeySpec(secretAccessKey.getBytes(), "HmacSHA256")
    val mac = Mac.getInstance(key.getAlgorithm())
    mac.init(key)
    val signature = new String(Base64.encodeBase64(mac.doFinal(strToSign.getBytes())))

    val url = new URL(baseUrl.toString() + "?" + canonicalStr + "&Signature=" + encodeUrl(signature))

    val br = new BufferedReader(new InputStreamReader(url.getContent().asInstanceOf[InputStream], "UTF-8"))
    val xmlSb = new StringBuilder()
    try {
      Iterator.continually(br.readLine).takeWhile(_ != null).foreach { line =>
        xmlSb.append(line)
      }
    } finally {
      br.close()
    }

    XML.loadString(xmlSb.toString())    // Amazonから返ってきた検索結果のXMLオブジェクトを作成

ファイルのエンコードはUTF-8にしてください。
encodeUrl関数を定義していますが、RFC3986準拠が正確ではないので、
コピペするときは注意してください。

参考

http://d.hatena.ne.jp/p4life/20090510/1241954889

0 件のコメント: