AmazonAPIを使った何かを作ってみる – 2.5 (VBAによるXML解析)


<前回の記事>

前回は使用できるレスポンスグループの一覧を確認する所まででした。

早速組み合わせて何か作ろう・・・と思ったのですが、まずは既存のプログラムを修正してXMLから目的のデータを取得する機能、いわゆるパーサ(構文解析)を作る事が先だと気付きました。

という訳で今回は少し逸れて、XML解析に重点を置いた番外編2.5となります。

スポンサーリンク

XMLオブジェクトの生成

まず既存の処理でXMLをやり取りする部分の処理を確認します。

'XML オブジェクト作成
Set xml = CreateObject("Microsoft.XMLDOM")
    xml.Async = False
    xml.Load URI
Set itemAttributes = xml.SelectSingleNode("ItemLookupResponse/Items/Item/ItemAttributes")

まずここで使われていた「Microsoft.XMLDOM」については既にサポート切れ?で古い処理の様なので、「MSXML2.XMLHTTP」と「MSXML2.DOMDocument」を用いた処理に変更します。

[修正後]
'==========================================================
' 指定したURLのレスポンスXMLをMSXML2.DOMDocument形式で返す
'==========================================================
Public Function getXMLDoc(url As String) As MSXML2.DOMDocument
    Dim objXML As Object        'サイトデータの格納先
    Dim objDoc As Object        'ドキュメントの格納先

    'XMLHTTPオブジェクトを生成
    Set objXML = CreateObject("MSXML2.XMLHTTP")

    On Error Resume Next
    Call objXML.Open("GET", url, False)
    Call objXML.send

    'ロード完了まで待つ
    Do While objXML.readyState <> 4
        Sleep 100
        DoEvents
    Loop

    'DOM操作を行える様にする
    Set objDoc = New MSXML2.DOMDocument
    objDoc.LoadXML objXML.responseText

    Set getXMLDoc = objDoc
End Function

この「getXMLDoc」にエンコード後のURLを投げると、「MSXML2.DOMDocument」形式にてオブジェクトが返ってきます。

「MSXML2.DOMDocument」を使用する際は参照設定が必要になりますので、事前に以下の「Microsoft XML v6.0」にチェックを入れておきましょう。

これを呼び出し側の処理で受け取ることで、以前の処理で言う所の

Set xml = CreateObject("Microsoft.XMLDOM") 
xml.Async = False 
xml.Load URI

この辺まで置き換えが完了した事になります。

これだけ見ると「以前の処理の方が行数少なくてシンプルで良いじゃん。」って思いますよね。

・・・そうなんですよねー

まぁ私自身も具体的に「Microsoft.XMLDOM」と「MSXML2.DOMDocument」がどう違うのかっていうのを説明できないので申し訳無いのですが・・・。

とりあえず「古い」という事は今後使えなくなる可能性が十分にあります。素直に置き換えておいた方が無難です。

ちなみにAmazonAPIを使ってデータを取得しようとする際、エラーになる事がよくあります。

ウォッチウィンドウで見てみると、成功時は以下の様なステータスに。

statusに200が返って来ていればOKです。

失敗時は以下の様なステータスになります。

statusが503だとパラメータの取得に失敗している状態ですので、再度要求し直す必要があります。

503」自体はWebサーバーへの同時アクセス数の制限をこえた場合や、Webサーバーがメンテナンス中などにより、リクエストに応答できない場合に出力されるエラーコードです。

ですが『いつ』、『どの時間帯に』やっても大体数回に1回は発生します。(笑)

なので実際に使用する場合は200が返ってくるまで数秒間隔でループさせる処理にした方が良さそうですね。

スポンサーリンク

XMLDocumentからパラメータを抽出

では取得したXMLデータから、特定のパラメータ値を取り出してみましょう。

今回使用したXMLは以下のものです。

<?xml version="1.0" ?>
<ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
  <OperationRequest>
    (省略)
  </OperationRequest>
  <Items>
    <Request>
      <IsValid>True</IsValid>
      <ItemLookupRequest>
        <IdType>ASIN</IdType>
        <ItemId>B010EB1KL2</ItemId>
        <ResponseGroup>SalesRank</ResponseGroup>
        <VariationPage>All</VariationPage>
      </ItemLookupRequest>
    </Request>
    <Item>
      <ASIN>B010EB1KL2</ASIN>
      <SalesRank>3968</SalesRank>
    </Item>
  </Items>
</ItemLookupResponse>

これはAmazonAPIを使用して、レスポンスグループに「SalesRank」を指定した際に返されたXMLです。

この中から「SalesRank」の『3968』という値を取り出してみます。

まず、以下従来のサンプル部分から

'不足が出るので=で埋める
sign = sign & "="

'URLエンコード
sign = UrlEncode(sign)
URI = "http://" & ecsaddress & "/onca/xml?" & rawText & "&Signature=" & sign

'XML オブジェクト作成
Set xml = CreateObject("Microsoft.XMLDOM")
    xml.Async = False
    xml.Load URI
Set itemAttributes = xml.SelectSingleNode("ItemLookupResponse/Items/Item/ItemAttributes")

URLエンコード処理より下の部分を全て削除し、以下の処理を記述します。

Dim XMLDocument As MSXML2.DOMDocument
Dim xmlData As IXMLDOMNode

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

'不足が出るので=で埋める
sign = sign & "="

'URLエンコード
sign = UrlEncode(sign)
URI = "http://" & ecsaddress & "/onca/xml?" & rawText & "&Signature=" & sign

Set XMLDocument = getXMLDoc(URI)
Set xmlData = XMLDocument.SelectSingleNode("//ItemLookupResponse/Items/Item/SalesRank")
MsgBox xmlData.text

あ、

Dim XMLDocument As MSXML2.DOMDocument
Dim xmlData As IXMLDOMNode

上記2つの定数も忘れずに宣言追加しておいて下さい。

そして冒頭で記述した「getXMLDoc」関数をどこかに記述した状態で実行させると・・・

 

と出るはずです。

<ItemLookupResponse>の中にある、

<Items>の中にある、

<Item>の中にある、

<SalesRank>を抽出したいと言う場合には、

SelectSingleNode(“//ItemLookupResponse/Items/Item/SalesRank“)

という風に指定すれば値を取り出せるという事ですね。

同じ様に<Request>の中にある<ItemId>を取り出したい場合は、

SelectSingleNode(“//ItemLookupResponse/Items/Request/ItemId“)

となります。

データの切り出しは意外と簡単でしたね!(調べて検証してここまで纏めるのに2日掛かりましたが)

これさえ分かれば後のパラメータも簡単に取得できると思いますので、ぜひ試してみて下さい。

複数の商品の情報が返って来た場合、全く同じ名前のノードが複数個存在する事になりますが、その場合の処理はまた今度考えましょう。

今回はこの辺で終了となります。

ではまた!

<次の記事>

関連記事と広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする