C#でAmazonのMWSを使用して,マケプレの出品情報を取得する

Amazonでは、Marketplace WebService API(Amazon MWS)を使用することで、マーケットプレースに出品されている商品の出品情報を取得する事が出来ます。
今回は、VisualStudioよりC#を使用して、マケプレの出品情報を取得するプログラムを作成してみます。
(phpで同じことをしたい場合はこちらの記事を参考にしてください)

Amazonマーケットプレイス徹底活用

サンプルプログラムの実効結果

今回のサンプルプログラムによって、以下の様なデータを取得できます。
結果が長いので一部省略しています。


=============================================================================
Status : Success
ASIN  : 4478312141
------------------------------------------------
コンディション   :中古品 良い
出荷元           :出品者
国内より発送     :True
発送日数(最大)   :0-2 days
フィードバック数 :93 (高評価率:95-97%)
出品数           :2
総額             :\1110(送料:\250)
------------------------------------------------
コンディション   :中古品 非常に良い
出荷元           :出品者
国内より発送     :True
発送日数(最大)   :0-2 days
フィードバック数 :842 (高評価率:98-100%)
出品数           :1
総額             :\1110(送料:\250)
------------------------------------------------
コンディション   :中古品 良い
出荷元           :FBA
国内より発送     :True
発送日数(最大)   :0-2 days
フィードバック数 :15683 (高評価率:95-97%)
出品数           :4
総額             :\1155(送料:\0)
 
...中略...
 
=============================================================================
Status : Success
ASIN  : 4797330058
------------------------------------------------
コンディション   :中古品 非常に良い
出荷元           :出品者
国内より発送     :Unknown
発送日数(最大)   :0-2 days
フィードバック数 :6 (高評価率:98-100%)
出品数           :1
総額             :\675(送料:\250)
------------------------------------------------
コンディション   :中古品 良い
出荷元           :出品者
国内より発送     :True
発送日数(最大)   :0-2 days
フィードバック数 :356918 (高評価率:95-97%)
出品数           :4
総額             :\675(送料:\250)
...
hit any key



一回のAPI呼び出しで、プログラム内にハードコーディングした2つのASINの出品情報を取得しています。

Amazon MWS APIの概要


Amazon MWSのAPIについて、基本的な情報は以下の記事を参考にしてください。

APIによる商品情報取得
Amazon MWSで商品の情報を取得する « nanoblog

APIの呼び出し回数の制限
Amazon MWSのAPIリクエスト制限の仕組み « nanoblog

MWSの商品APIをコールした時の実行結果例(xmlの生データ)
Amazon MWS商品APIの実行結果例 « nanoblog


商品情報の取得には、GetLowestOfferListingsForASINのAPIを使用します。
このAPIの仕様はAmazonのサイトにも記載されていますが、呼び出し頻度に上限があり20回/分を超えるとエラーになります。また商品情報の取得は、API呼び出し一回で最大20ASINまで指定可能です。

マーケットプレースでは、1つの商品に対して複数の出品(多い時は100件以上)が有りますが、APIで取れるのは価格が低いほうから10件程度のようです。この制限は、APIのパラメータを工夫することで後続のデータを取得する事も可能です。


データの取得には、Amazonから提供されているクライアントライブラリを使用しています。
クライアントライブラリはdll形式になっており、このdllはAmazonから提供されているソースをビルドすれば入手できます。

ですので、VisualStudioさえあればdllは誰でも用意できるのですが、dllを作るのが面倒な人の為にビルド済みのdllを置いておきます。
ダウンロード:MarketplaceWebServiceProducts_dll.zip

また、Amazon MWSのAPIを使用するには、マーケットプレースに大口出品者として登録している必要があります(大口出品者でないとAPI呼び出しに必要なIDが手に入りません)。



API呼び出しのサンプルプログラム

それでは、サンプルのプログラムです。
200行以上有りますが、ほとんどはshowResponse()メソッドで、これは取得したデータを画面に出力する処理なので、実質はMain()メソッドの50行程度です。

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using MarketplaceWebServiceProducts;
using MarketplaceWebServiceProducts.Mock;
using MarketplaceWebServiceProducts.Model;
 
public class MwsTest {
    private static string accessKeyId     = "xxxx";		// 設定してください!!
    private static string secretAccessKey = "xxxx";		// 設定してください!!
    private static string merchantId      = "xxxx";		// 設定してください!!
    private static string marketplaceId   = "xxxx";		// 設定してください!!
 
    public static void Main(string [] args) {
 
        MarketplaceWebServiceProductsConfig config = new MarketplaceWebServiceProductsConfig();
        config.ServiceURL = "https://mws.amazonservices.jp/Products/2011-10-01";
 
        //-------------------------------------
        // WebService情報オブジェクトを取得
        //-------------------------------------
        MarketplaceWebServiceProductsClient service = new MarketplaceWebServiceProductsClient(
                         "nanoappli.com_sample", "1.0.0.0", accessKeyId, secretAccessKey, config);
 
 
        //-------------------------------
        // リクエストパラメータのセット
        //-------------------------------
        GetLowestOfferListingsForASINRequest request = new GetLowestOfferListingsForASINRequest();
 
        ASINListType asinList = new ASINListType();
        asinList.ASIN = new List<string>();
        asinList.ASIN.Add( "4478312141" );
        asinList.ASIN.Add( "4797330058" );
 
        request.ASINList      = asinList;
        request.SellerId      = merchantId;
        request.MarketplaceId = marketplaceId;
 
        //-------------------------------
        // MWSリクエストAPIの実行
        //-------------------------------
        GetLowestOfferListingsForASINResponse response = null;
        try {
            response = service.GetLowestOfferListingsForASIN(request);
        } 
        catch (MarketplaceWebServiceProductsException ex) 
        {
            Console.WriteLine("Caught Exception: " + ex.Message);
            Console.WriteLine("Response Status Code: " + ex.StatusCode);
            Console.WriteLine("Error Code: " + ex.ErrorCode);
            Console.WriteLine("Error Type: " + ex.ErrorType);
            Console.WriteLine("Request ID: " + ex.RequestId);
            Console.WriteLine("XML: " + ex.XML);
            Console.WriteLine("ResponseHeaderMetadata: " + ex.ResponseHeaderMetadata);
        }
 
        showResponse( response );
 
        Console.WriteLine("hit any key");
        Console.ReadKey();
    }
 
 
    //****************************************************************************
    // Function     : showResponse
    // Description  : Webサービス実行結果の表示
    // Params       : response WebAPI実行結果
    //****************************************************************************
    public static void showResponse( GetLowestOfferListingsForASINResponse response ) {         
 
        List<GetLowestOfferListingsForASINResult> resultList = response.GetLowestOfferListingsForASINResult;
        foreach (GetLowestOfferListingsForASINResult getLowestOfferListingsForASINResult in resultList) {
            Console.WriteLine ("=============================================================================");
            if (getLowestOfferListingsForASINResult.IsSetstatus()) {
                Console.WriteLine("Status : {0}",  getLowestOfferListingsForASINResult.status);
            } 
 
            //----------------
            // 商品の情報
            //----------------
            if (getLowestOfferListingsForASINResult.IsSetASIN()) {
                Console.WriteLine("ASIN  : {0}",  getLowestOfferListingsForASINResult.ASIN);
            } 
 
            if (getLowestOfferListingsForASINResult.IsSetProduct()) {
                Product  product = getLowestOfferListingsForASINResult.Product;
 
                if (product.IsSetSalesRankings()){
                    SalesRankList  salesRankings = product.SalesRankings;
                    List<SalesRankType> salesRankList = salesRankings.SalesRank;
                    foreach (SalesRankType salesRank in salesRankList) {
                        Console.WriteLine("                        SalesRank");
                        if (salesRank.IsSetProductCategoryId())
                        {
                            Console.WriteLine("カテゴリID :{0}", salesRank.ProductCategoryId);
                        }
                        if (salesRank.IsSetRank())
                        {
                            Console.WriteLine("ランク :{0}", salesRank.Rank);
                        }
                    }
                }
 
 
                if (product.IsSetLowestOfferListings()) {
                    LowestOfferListingList  lowestOfferListings = product.LowestOfferListings;
                    List<LowestOfferListingType> lowestOfferListingList = lowestOfferListings.LowestOfferListing;
 
                    //-----------------------------------------
                    // 取得した全出品情報を表示するまで繰り返し
                    //-----------------------------------------
                    foreach (LowestOfferListingType lowestOfferListing in lowestOfferListingList) {
                        Console.WriteLine("------------------------------------------------");
 
                        if (lowestOfferListing.IsSetQualifiers()) {
                            QualifiersType  qualifiers = lowestOfferListing.Qualifiers;
                            if (qualifiers.IsSetItemCondition()) {
                                String condName    = getConditionName( qualifiers.ItemCondition );
                                String subCondName = "";
                                if (qualifiers.IsSetItemSubcondition()) {
                                    subCondName = getItemSubconditionName( qualifiers.ItemSubcondition );
                                }
                                Console.WriteLine("コンディション   :{0} {1}", condName, subCondName );
 
                            }
 
                            if (qualifiers.IsSetFulfillmentChannel()) {
                                Console.WriteLine("出荷元           :{0}", qualifiers.FulfillmentChannel);
                            }
                            if (qualifiers.IsSetShipsDomestically()) {
                                Console.WriteLine("国内より発送     :{0}", qualifiers.ShipsDomestically);
                            }
                            if (qualifiers.IsSetShippingTime() && qualifiers.ShippingTime.IsSetMax()) {
                                Console.WriteLine("発送日数(最大)   :{0}", qualifiers.ShippingTime.Max);
                            }
                            if (lowestOfferListing.IsSetSellerFeedbackCount()) {
                                Console.Write("フィードバック数 :{0}", lowestOfferListing.SellerFeedbackCount);
                                if (qualifiers.IsSetSellerPositiveFeedbackRating()) {
                                    Console.Write(" (高評価:{0})", qualifiers.SellerPositiveFeedbackRating);
                                }
                                Console.WriteLine("");
                            }
 
 
                        }
                        if (lowestOfferListing.IsSetNumberOfOfferListingsConsidered()) {
                            Console.WriteLine( "出品数           :{0}", lowestOfferListing.NumberOfOfferListingsConsidered);
                        }
 
                        //------------------
                        // 価格情報
                        //------------------
                        if (lowestOfferListing.IsSetPrice()) {
                            PriceType  price1 = lowestOfferListing.Price;
                            if (price1.IsSetLandedPrice()) {
                                Console.Write( "総額             :" + getPriceName( price1.LandedPrice ) );
                            }
 
                            if (price1.IsSetShipping()) {
                                Console.WriteLine( "(送料:" + getPriceName( price1.Shipping ) + ")" );
                            }
                        }
                    }
                }
 
 
            }
 
            if (getLowestOfferListingsForASINResult.IsSetError()) {
                Console.WriteLine( "エラーが発生しました" );
                Error  error = getLowestOfferListingsForASINResult.Error;
                if (error.IsSetType()) {
                    Console.WriteLine("Type: {0}", error.Type);
                }
                if (error.IsSetCode()) {
                    Console.WriteLine("Code: {0}", error.Code);
                }
                if (error.IsSetMessage()) {
                    Console.WriteLine("Message: {0}", error.Message);
                }
            }
        }
 
    }
 
 
    //****************************************************************************
    // Function     : getConditionName
    // Description  : コンディション名(日本語)を取得する
    //****************************************************************************
    private static string getConditionName( string inStr ) {
        switch( inStr ) {
            case "New":
                return "新品";
            case "Used":
                return "中古品";
            case "Collectible":
                return "コレクター品";
            case "Refurbished":
                return "再生品";
            default:
                return inStr;
        }
    }
 
    //****************************************************************************
    // Function     : getItemSubconditionName
    // Description  : サブコンディション名(日本語)を取得する
    //****************************************************************************
    private static string getItemSubconditionName( string inStr ) {
        switch( inStr ) {
            case "New":
                return "新品";
            case "Mint":
                return "ほぼ新品";
            case "Very Good":
            case "VeryGood":
                return "非常に良い";
            case "Good":
                return "良い";
            default:
                return inStr;
        }
    }
 
    //****************************************************************************
    // Function     : getFulfillmentChannelName
    // Description  : 出荷元(日本語)を取得する
    //****************************************************************************
    private static string getFulfillmentChannelName( string inStr ) {
        switch( inStr ) {
            case "Amazon":
                return "FBA";
            case "Merchant":
                return "出品者";
            default:
                return inStr;
        }
    }
 
 
    //****************************************************************************
    // Function     : getPriceName
    // Description  : 価格(通貨単位付き)を取得する
    //****************************************************************************
    private static string getPriceName( MoneyType inData ) {
        string outStr = "";
 
        // 通貨単位のセット
        if ( inData.IsSetCurrencyCode() ) {
            switch ( inData.CurrencyCode ) {
                case "JPY":
                    outStr += "\\";
                    break;
                case "USD":
                    outStr += "$";
                    break;
                default:
                    outStr += "(" + inData.CurrencyCode + ")";
                    break;
            }
        }
 
        // 金額のセット
        if ( inData.IsSetAmount()) {
            outStr += String.Format( "{0:0}", inData.Amount );
        }
 
        return outStr;
    }
}



DLLでは、各APIメソッド毎にクラスが用意されており、出品情報の取得に使用するクラスはGetLowestOfferListingsForASINRequestです。API仕様と見比べると”APIの名称+Request”がクラス名になっていることが分かります。

requestオブジェクトは、検索条件を指定するためのプロパティがありますので、適宜設定していきます。
必須パラメータを設定し忘れると、API呼び出し時にエラーとなります。

その後、WebServiceを管理するためのオブジェクトであるMarketplaceWebServiceProductsClientクラスのインスタンスを生成します。serviceオブジェクトのメソッドに、先ほど作ったrequestを引数として渡す事でAPI呼び出しが行われます。

API呼び出しの結果は、戻り値のresponseオブジェクトより取得します。
応答データには結果値が省略可能な項目も有あります。実際にデータが取れたかはIsSetXXXX()メソッドで確認可能なので、一旦確認した上でデータを取り出します。

取得データは原則として英語なので、サンプルプログラムでは、getConditionName()等のアクセサを使用して日本語に変換しています。

自分でプロジェクトを作るには…


このサンプルプログラムを、プロジェクト作成のところから自分で全部したい場合は、以下の手順で作業します。

プロジェクトを新規作成します。

メニューバーの”プロジェクト->参照の追加”よりMarketplaceWebServiceProducts.dllを参照設定します。


前述のコードをコピー&ペーストします。

コード先頭にある以下のIDを設定します。
セットする値の取得方法はこちらの記事を参照してください。

    private static string accessKeyId     = "xxxx";		// 設定してください!!
    private static string secretAccessKey = "xxxx";		// 設定してください!!
    private static string merchantId      = "xxxx";		// 設定してください!!
    private static string marketplaceId   = "xxxx";		// 設定してください!!




設定が面倒な場合は、プロジェクトファイルごと用意したので、ダウンロードした上で適当に改造してみてください。このプロジェクトファイルはVisual Stdio 2010の環境で.NetFramework 4.0を使用して作成しています。
ダウンロード:AmazonMwsSample.zip


関連記事

4 Responses to “C#でAmazonのMWSを使用して,マケプレの出品情報を取得する”

  1. 矢崎 より:

    初めまして!突然のご連絡すみません。連絡先がなかったのでこちらに書かせていただきました。

    AmazonMWSを使用できるエンジニアを探していました。実は開発して欲しいシステムがあるのですがご連絡いただけないでしょうか?よろしくお願いします。

  2. Reno より:

    勉強させて頂いております。
    MWSの仕様について、ご教示ください。
    >マーケットプレースでは、1つの商品に対して複数の出品(多い時は100件以上)が有りますが、APIで取れるのは価格が低いほうから10件程度のようです。この制限は、APIのパラメータを工夫することで後続のデータを取得する事も可能です。

    ・・とありますが、文献を調べてもヒントすら得られません。
    GetLowestOfferListingsForASINRequestクラスにも、後続のデータを取得するために設定できそうなプロパティが見当たりません。
    どう設定すれば後続データが取得できますか?
    どうか教えてください。

  3. オオイ より:

    初めまして。
    大変申し訳ないのですが、クライアントライブラリからdllの作成方法を教えて頂けないでしょうか?
    AmazonからダウンロードしたMarketplaceWebServiceProducts.csがビルド出来ず困っております・・・

  4. オオイ より:

    すいません、自己解決しました。

Reno へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。