Amazon MWS から SP-API への移行 [PythonでSP-APIをたたく編]

これまでのブログ記事(以下)では、AmazonのMWSの後継となるSelling Partner API(以下、SP-API)へ移行するための準備をしてきました。

今回は「PythonでSP-APIをたたく編」ということで、実際にPythonプログラムを作成してSP-APIをたたいてみて、使い方を理解していきたいと思います。

この記事でできるようになること

  • PythonプログラムでSP-APIのたたき方、使い方が理解できるようになる
  • MWSからSP-APIへの移行ができるようになる

なお、今後SP-APIを利用する際にあまり困らなくなるので、ちょっと元気が出ます。

必要となる知識

  • Pythonプログラミングの知識
  • JSONの知識
  • サーバーの基本的な知識
  • GETやPOSTといったHTTPプロトコルの仕組みの知識
  • 公式リファレンス(英語)に記載のSP-APIの仕様を読み解く力(Google翻訳はみんなの友達!)

公式リファレンスはこちら

私の実装内容は、基本的には公式リファレンスに全て書いてあります。(が、理解することが難しい書き方になっています。)なので、特別なことは何もしておらず、どなたにでもオープンな情報になっています。

SP-API 公式リファレンス

 SellingPartnerApiDeveloperGuide(日本語)

署名プロセス 公式リファレンス

 AWS > ドキュメント > リファレンスガイド > 署名バージョン4の署名プロセス

署名プロセスが難解すぎるっ!!!

こちらを参考に、プログラムを作ればいいだけですってことなのかと思いますが、、、

Pythonを動かす環境

今回のブログでは開発環境の準備方法については割愛しますが、私のPythonプログラム開発環境は以下です。

  • サーバー環境
    • 契約 : Conoha
    • OS : Cent OS 7
  • プログラミング環境
    • OS : Windows10
    • 統合開発環境 : Visual Studio Code
    • 言語 : Python
  • Pythonバージョン
    • Python 3.6.8

やばい、Python3.6系のセキュリティ修正パッチの提供終了予定が2021年12月... バージョン上げないといけないですね。

アクセスするSP-APIのAPIを決める

前回のブログ「Postmanによるテスト接続編」では、SP-APIの「getCatalogItem」というAPIをPostmanでたたいてResponseを取得しました。今回は前回同様のAPIをPythonでたたきます。PostmanでのAPIアクセス方法とPythonでのAPIアクセス方法を比較することで、PythonによるAPIプログラミングの感覚がつかめると思います。

Selling Partner API for Catalog Items

Overvies : The Selling Partner API for Catalog Items provides programmatic access to information about items in the Amazon catalog.

概要 : Selling Partner API 「Catalog Items」は、プログラムによるAmazonカタログ内のアイテムに関する情報へのアクセスを提供します。

https://github.com/amzn/selling-partner-api-docs/blob/4b53b4e38bcb5745266f53cdf65feed2b56e0ddc/references/catalog-items-api/catalogItems_2020-12-01.md

Pythonサンプルプログラムとレスポンス

早速ですが、以下にPythonのサンプルプログラムを記載します。

アクセストークン取得

前回の読み解きを再掲します。こちらをアクセストークン取得のPythonプログラムに設定します。

アクセストークン取得のためのリクエスト設定

LWA(Login with Amazon)認証サーバーに対して、必要なパラメータをセットしてRequestを送信します。

  • LWA認証サーバURL
    • https://api.amazon.com/auth/o2/token
  • HTTP メソッド
    • POST
  • POSTリクエストのBodyパラメータ
    • grant_type:「refresh_token」という文字列を設定
    • refresh_token:「リフレッシュトークン」の値を設定
    • client_id:「LWA 認証情報 クライアントID」を設定
    • client_secret:「LWA 認証情報 クライアント機密情報」を設定

まずはリフレッシュトークンからアクセストークンを取得する関数です。必要となるモジュールは適宜 import してください。

### =====================================================================================
### Access Token 取得関数
### =====================================================================================

### 初期モジュール宣言
import os,sys,time
import hashlib
import hmac
import urllib.parse
import requests
import json
from time import gmtime, strftime
from datetime import datetime

def SPAPI_Get_Token(SPAPI_LWA_Client_ID, SPAPI_LWA_Client_PW, SPAPI_Refresh_Token, SPAPI_Access_Token_Endpoint):
    print("Func : SPAPI_Get_Token")
    
    ### === 引数の説明 ================================================
    ### SPAPI_LWA_Client_ID           : LWA 認証情報 クライアントID
    ### SPAPI_LWA_Client_PW           : LWA 認証情報 クライアント機密情報
    ### SPAPI_Refresh_Token           : リフレッシュトークン
    ### SPAPI_Access_Token_Endpoint   : LWA認証サーバURL
    ### ==============================================================

    ### 認証情報の作成
    auth = (SPAPI_LWA_Client_ID, SPAPI_LWA_Client_PW)
    
    ### POSTパラメータ作成
    params = {
        "grant_type":"refresh_token",
        "refresh_token":SPAPI_Refresh_Token
    }

    ### POSTリクエスト処理の実行
    SPAPI_Response = requests.post(url=SPAPI_Access_Token_Endpoint, auth=auth, data=params)

    ### レスポンスをDict型へデコード
    SPAPI_Response_dict = SPAPI_Response.json()


    ### POST後のHTTPレスポンスコードとレスポンス内容の表示(確認用)
    print(SPAPI_Response, flush=True)
    print(json.dumps(SPAPI_Response_dict, indent=2, ensure_ascii=False), flush=True)

    ### 値の取得
    resp_access_token = SPAPI_Response_dict['access_token']
    resp_refresh_token = SPAPI_Response_dict['refresh_token']
    resp_token_type = SPAPI_Response_dict['token_type']
    resp_expires_in = SPAPI_Response_dict['expires_in']

    return resp_access_token, resp_refresh_token, resp_token_type, resp_expires_in

こちらを関数として配置し、メイン関数から呼び出し実行すると、以下のような応答が返ってきます。無事、アクセストークンが取得できています。

Func : SPAPI_Get_Token

<Response [200]>

{
  "access_token": "Atza|~~~省略~~~",
  "refresh_token": "Atzr|~~~省略~~~",
  "token_type": "bearer",
  "expires_in": 3600
}

セキュリティ的に危ない部分は「~~~省略~~~」と置換しています。

SP-API の API アクセス

こちらも、前回の読み解きを再掲します。一部は修正/追記してます。SP-API公式リファレンスから以下の読み解きができるようになれば、SP-APIは自由自在に扱えるかと思います。

getCatalogItem 情報取得のためのリクエスト設定
  • HTTPメソッド
    • GET
  • SP-API エンドポイント
    • https://sellingpartnerapi-fe.amazon.com
  • Path
    • /catalog/2020-12-01/items/{asin}
      ※{asin} には Amazon の商品に付与されているASINコードを入れる
    • asin:SP-APIから情報を取得したいASINコードを入力する
      ※今回は「B07WXL5YPW」(Nintendo Switch)を入力
  • GETリクエストのパラメータ(クエリ部分)
    • marketplaceIds:「A1VC38T7YXB528」を設定
    • includedData : 「identifiers」「images」「productTypes」「salesRanks」「summaries」「variations」を設定
      ※こちらのリファレンス(includedData)を参照
  • ヘッダー情報作成のためのパラメータ
    • user-agent:アクセスした際に識別可能なUserAgent情報を記載する
      ※例:Zats-SPAPI-App/Ver1.0 (Tool=Postman;Platform=Windows10)
    • x-amz-access-token:リフレッシュトークンから取得した「アクセストークン」を設定
  • 認証情報(Authorization)作成のためのパラメータ
    • AccessKey:「AWS IAMユーザー アクセスキーID」を設定
    • SecretKey:「AWS IAMユーザー シークレットアクセスキー」を設定
    • AWS Region:「us-west-2」を設定
    • Service Name:「execute-api」を設定

取得したアクセストークンを用いて、かつ上記の読み解き結果を参考にしながら「getCatalogItem」APIをたたきます。こちらも、 必要となるモジュールは適宜 import してください。

### =====================================================================================
### SP-API「getCatalogItem」にアクセスし、指定したASINコードの商品情報を取得する関数
### =====================================================================================

### 初期モジュール宣言
import os,sys,time
import hashlib
import hmac
import urllib.parse
import requests
import json
from time import gmtime, strftime
from datetime import datetime

def SPAPI_GetCatalogItemsForASIN(Asin_Code, SPAPI_Access_Token, SPAPI_IAM_User_Access_Key, SPAPI_IAM_User_Secret_Key, SPAPI_Method, SPAPI_Service, SPAPI_Domain, SPAPI_MarketplaceId, SPAPI_Region, SPAPI_Endpoint, SPAPI_SignatureMethod, SPAPI_UserAgent):
    print('Function : SPAPI_GetCatalogItemsForASIN')

    ### === 引数の説明 ============================
    ### Asin_Code                   : リクエストするASINコード
    ### SPAPI_Access_Token          : リフレッシュトークンから取得したアクセストークン
    ### SPAPI_IAM_User_Access_Key   : IAMユーザのアクセスキー
    ### SPAPI_IAM_User_Secret_Key   : IAMユーザのシークレットキー
    ### SPAPI_Method                : HTTPアクセスプロトコル(GET)
    ### SPAPI_Service               : IAMユーザのアクセス権限設定(execute-api)
    ### SPAPI_Domain                : SP-APIエンドポイントのURLのドメイン部分(sellingpartnerapi-fe.amazon.com)
    ### SPAPI_MarketplaceId         : APIリクエストするAmazonマーケットプレイスのID
    ### SPAPI_Region                : APIリクエストするエンドポイントのAWS Region
    ### SPAPI_Endpoint              : SP-APIエンドポイントのURL(https://を含むやつ)
    ### SPAPI_SignatureMethod       : 署名方式(AWS4-HMAC-SHA256)
    ### SPAPI_UserAgent             : APIリクエストする際のユーザエージェント情報(アクセス識別用)
    ### ==========================================

    ### ====================
    ### SP-API Path の定義
    ### ====================
    # ### Version : 0 ★2022年3月31日で使えなくなる★
    # ## パス設定
    # SPAPI_API_Path = '/catalog/v0/items/{}'.format(Asin_Code)
    # ## リクエストパラメータ設定
    # request_parameters = 'MarketplaceId=' + str(SPAPI_MarketplaceId)

    ### Version : 2020-12-01
    ## パス設定
    SPAPI_API_Path = '/catalog/2020-12-01/items/{}'.format(Asin_Code)
    ## リクエストパラメータ設定(パラメータはアルファベット順にすること! & URLエンコードしないと、リクエストエラーになる場合あり!カンマ区切り文字入れるならURLエンコード必須)
    request_parameters_unencode = {
        'includedData' : 'identifiers,images,productTypes,salesRanks,summaries,variations',
        'marketplaceIds' : str(SPAPI_MarketplaceId)
    } 
    request_parameters = urllib.parse.urlencode(request_parameters_unencode)
    

    ### Python による署名キーの取得関数
    ## 参考:http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
    def sign(key, msg):
        return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

    def getSignatureKey(key, dateStamp, regionName, serviceName):
        kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
        kRegion = sign(kDate, regionName)
        kService = sign(kRegion, serviceName)
        kSigning = sign(kService, 'aws4_request')
        return kSigning

    ### ヘッダー情報と問合せ資格(credential)情報のための時刻情報作成
    t = datetime.utcnow()
    amzdate = t.strftime('%Y%m%dT%H%M%SZ')
    datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope


    ### =================================================================================
    ### Canonical Request の作成
    ### 参考:http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
    ### =================================================================================

    ## URI設定
    canonical_uri = SPAPI_API_Path

    ## 正規リクエストパラメータ設定
    canonical_querystring = request_parameters

    ## 正規リクエストヘッダリストの作成
    canonical_headers = 'host:' + SPAPI_Domain + '\n' + 'user-agent:' + SPAPI_UserAgent + '\n' + 'x-amz-access-token:' + SPAPI_Access_Token + '\n' + 'x-amz-date:' + amzdate + '\n'

    ## 正規リクエストヘッダリストの項目情報の作成(hostとx-amz-dateも入れてる)
    signed_headers = 'host;user-agent;x-amz-access-token;x-amz-date'

    ## ペイロードハッシュ(リクエスト本文コンテンツのハッシュ)の作成
    ## ※GETリクエストの場合、ペイロードは空の文字列("")になる。
    payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()

    ## 正規リクエストの作成
    canonical_request = SPAPI_Method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash

    ## 問合せ資格情報を作成し、署名方式、ハッシュ化された正規リクエスト情報を結合した情報を作成する
    credential_scope = datestamp + '/' + SPAPI_Region + '/' + SPAPI_Service + '/' + 'aws4_request'
    string_to_sign = SPAPI_SignatureMethod + '\n' +  amzdate + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()

    ## 定義した関数を用いて署名鍵を作成
    signing_key = getSignatureKey(SPAPI_IAM_User_Secret_Key, datestamp, SPAPI_Region, SPAPI_Service)

    ## 署名鍵で、上記で作成した「string_to_sign」に署名
    signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()

    ## Authorizationヘッダの作成
    authorization_header = SPAPI_SignatureMethod + ' ' + 'Credential=' + SPAPI_IAM_User_Access_Key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature

    ## API問合せ用ヘッダ情報の作成
    headers = {'user-agent':SPAPI_UserAgent, 'x-amz-access-token':SPAPI_Access_Token, 'x-amz-date':amzdate, 'Authorization':authorization_header}

    ## APIリクエストURLの作成
    request_url = SPAPI_Endpoint + canonical_uri + '?' + request_parameters

    ### ====================
    ### SP-APIリクエスト
    ### ====================
    print('=== Request ===')
    print('Request URL = ' + request_url)
    api_response = requests.get(request_url, headers=headers)

    return api_response

表示するための簡単な構文は以下です。書いてなかった...
貴重なコメントいただいたので追記しました。 ありがとうございます。(2022.04.15)

## レスポンスをdict形式に変換
response_dict = json.loads(api_response.text)
## 見やすく表示する加工
response_json = json.dumps(response_dict, indent=4)

## 表示
print('=== Response detail - SPAPI_GetCatalogItemsForASIN ===')
print('Response Status : ' + str(api_response.status_code))
print('Response headers :\r\n' + str(api_response.headers))
print('Response json :\r\n' + str(response_json))

こちらも関数として配置し、アクセストークン取得関数と組み合わせてメイン関数から呼び出し実行することで、以下のような応答が返ってきます。無事、SP-APIの「 getCatalogItem 」から情報取得ができるようになるかと思います。

=== Function : SPAPI_GetCatalogItemsForASIN

=== Request ===
Request URL = https://sellingpartnerapi-fe.amazon.com/catalog/2020-12-01/items/B07WXL5YPW?includedData=identifiers%2Cimages%2CproductTypes%2CsalesRanks%2Csummaries%2Cvariations&marketplaceIds=A1VC38T7YXB528


=== Response 詳細 ===
Response Status : 200
Response headers :
{'Date': 'Wed, 08 Sep 2021 ~~~省略~~~ GMT', 'Content-Type': 'application/json', 'Content-Length': '1070', 'Connection': 'keep-alive', 'x-amzn-RequestId': '~~~省略~~~', 'x-amzn-RateLimit-Limit': '5.0', 'x-amz-apigw-id': '~~~省略~~~', 'X-Amzn-Trace-Id': '~~~省略~~~'}

=== Response 結果内容 ===
{
    "asin": "B07WXL5YPW",
    "identifiers": [
        {
            "marketplaceId": "A1VC38T7YXB528",
            "identifiers": [
                {
                    "identifier": "4902370542912",
                    "identifierType": "EAN"
                }
            ]
        }
    ],
    "images": [
        {
            "marketplaceId": "A1VC38T7YXB528",
            "images": [
                {
                    "variant": "MAIN",
                    "link": "https://~~~省略~~~.jpg",
                    "height": 324,
                    "width": 500
                }
            ]
        }
    ],
    "productTypes": [
        {
            "marketplaceId": "A1VC38T7YXB528",
            "productType": "ABIS_VIDEO_GAMES"
        }
    ],
    "ranks": [
        {
            "marketplaceId": "A1VC38T7YXB528",
            "ranks": [
                {
                    "title": "\u30b2\u30fc\u30e0",
                    "link": "http://www.amazon.jp/gp/bestsellers/videogames",
                    "value": 3
                },
                {
                    "title": "Nintendo Switch\u672c\u4f53",
                    "link": "http://www.amazon.jp/gp/bestsellers/videogames/4731379051",
                    "value": 1
                }
            ]
        }
    ],
    "summaries": [
        {
            "marketplaceId": "A1VC38T7YXB528",
            "brandName": "\u4efb\u5929\u5802",
            "browseNode": "4731379051",
            "colorName": "\u30cd\u30aa\u30f3\u30d6\u30eb\u30fc/\u30cd\u30aa\u30f3\u30ec\u30c3\u30c9",
            "itemName": "Nintendo Switch \u672c\u4f53 (\u30cb\u30f3\u30c6\u30f3\u30c9\u30fc\u30b9\u30a4\u30c3\u30c1) Joy-Con(L) \u30cd\u30aa\u30f3\u30d6\u30eb\u30fc/(R) \u30cd\u30aa\u30f3\u30ec\u30c3\u30c9",
            "manufacturer": "\u4efb\u5929\u5802",
            "sizeName": "\u672c\u4f53\u306e\u307f"
        }
    ],
    "variations": [
        {
            "marketplaceId": "A1VC38T7YXB528",
            "asins": [
                "B08NDDJJ35"
            ],
            "variationType": "CHILD"
        }
    ]
}

セキュリティ的に危ない部分や不要な部分、迷惑をかけそうな部分は「~~~省略~~~」と置換しています。

文字化け部分は、適宜エンコードすれば正しい表記に戻ります。

これで、無事SP-APIからAPI経由で欲しい情報を取得することができるようになりました。

こんなエラーが出たら

なお、こちらは前回記事からの再掲となりますが、アクセス権限の設定(IAMユーザへの権限ロール設定、Amazon Seller Central での権限ロール設定、その他権限設定まわり、等々)で何れかの設定が誤っていると、下記のエラーが出ます。

Status : 403

{
    "errors": [
        {
            "message": "Access to requested resource is denied.",
            "code": "Unauthorized",
            "details": "The access token you provided has expired."
        }
    ]
}

何度も書いちゃいますが、このエラーの厄介な点はどこが間違っているのかをエラーメッセージ内容から容易に特定できない点にあります。このエラーが出てしまった場合は、権限ロール設定の見直しから始めた方がよいかと思います。 権限ロール設定が間違ってない!という場合は、アクセストークンの有効期限切れ、署名ミス、等が考えられます。

他のエラーについても出る可能性はあります。公式リファレンスのエラーレスポンス内容を参考にデバッグを頑張りましょう。

Error Responses and Schemas

This table contains HTTP status codes and associated information for error responses.

まとめ

これまでの記事で準備した情報をもとに、本日のページの流れに従うことでPythonによるSP-APIへのアクセス、APIによる情報取得ができるようになったと思います。

他のプログラミング言語でも、SP-APIからの情報取得方法は基本的に同じになると思うので、こちらの記事を参考にSP-APIへアクセスをしていただき、アプリケーション開発の助けになれば嬉しいです。

「Amazon MWS から SP-API への移行」シリーズは今回で終了です。私としては、なかなかの超大作になってしまいました。今後も、頑張っている方々のお役に立てるような記事を書いていければと思っています。

SP-APIでこんなことしてくれないか、こんなWebアプリケーション作ってくれないか、というお仕事は大歓迎ですので、ご連絡お待ちしております。(ちょっとだけアピールです。)

では、今日はここまでです。お疲れさまでした。

コメント一覧
  1. 大島孝之 より:

    貴重な投稿ありがとうございます。
    4回やっても 404 で悩んでいます。
    Postmanでうまくいったのでサーバーサイドで、と思ってSP-APIを叩いていますが....

    上記プログラム、今もエラーなくレスポンスを返してくれますでしょうか?

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      コメントありがとうございます。404が解決できないとのことですね。
      ブログをチェックいただいている方々にご迷惑はかけられないので、現在手元で動かしているプログラムと
      ブログに記載している内容をあらためてDiffを取って確認してみました。

      結果、相違点なしでしたため問題なく動いている、というご回答となります。

      Tokenが上手く発行できないという状況でしょうか?

      • 大島孝之 より:

        おおーお忙し中、ご返信ありがとうございます、すごいですね。
        返信の有無はこちらのページにアクセスしないと分からないんですね、今後気をつけます。
        Tokenは大丈夫なようです。
        SPAPI_Get_Token() で発行した Access_Token を Postman で使うと、商品情報取得できています。

        今は 403 エラー中です。
        関数SPAPI_GetCatalogItemsForASIN() 内の 変数:headers を確認すると、 AWS IAM の ID が
        'Authorization': 'AWS4-HMAC-SHA256 Credential=
        の後についています。
        Postmanの方は、Credential= の後が
        https://sts.us-east-1.amazonaws.com/?Action=AssumeRole&DurationSeconds=3600&RoleArn=arn:aws:iam:・・・・・・・・
        に GET リクエストした結果の AccessKeyId 。
        もし何か思い当たることございましたら、教えて頂けると有り難いです。

  2. 大島孝之 より:

    お騒がせしました、行けました。
    原因は最初にSP-APIを叩くときに設定したAWSのIAMが、本稿含め、一般論と違ったためレスポンスがもらえませんでした。
    最初は、https://www.cdatablog.jp/entry/amazonspapihowto04を参考にAWSのIAMでロールの設定をして、Amazon Sellerのアプリに登録。そのため商品情報等を取得するまでに一度アクセスキー等を取り直す必要がありました。
    SP-API、エラーの際何がいけないのか本当に特定困難ですね。
    貴重な情報提供ありがとうございます。(noteでは5000円ぐらいの価値がありそうなコンテンツと思います‍♂️)

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      コメントありがとうございます。お返事遅くなってしまいすみません...
      私の方のプログラム、本当に大丈夫なのか!?と思い見直し作業をしていました。解決できたとのことでよかったです。ホッとしました。

      認証系のエラーですが、体験された通り特定困難ですよね。
      もう少しエラーにヒントを!と思いつつ認証系のエラーは詳しくするとそれはそれでセキュリティ的にもまずいので曖昧にしているのでしょうか。難しい所です。

      記事がお役に立てたようで良かったです!

      noteで5,000円という評価までいただけて光栄です。浮いた5000円で美味しいものでも食べていただければ嬉しいです!

  3. 川口 より:

    getCatalogItemのsalesRanksは、そのAPIを実行した時点のセールスランキングですか?
    例えば、その商品の過去3ヶ月とか1年のランキング推移のデータが欲しい時は、どうすれば良いのでしょうか?

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      >getCatalogItemのsalesRanksは、そのAPIを実行した時点のセールスランキングですか?
      はい、APIを実行した時点でのランキングになるかと思います。
      Github Document : https://github.com/amzn/selling-partner-api-docs/blob/main/references/catalog-items-api/catalogItemsV0.md

      >例えば、その商品の過去3ヶ月とか1年のランキング推移のデータが欲しい時は、どうすれば良いのでしょうか?
      こちらは、Keepa等の外部サービス(有料)を利用する必要があるかと思います。
      Keepa APIであれば、過去に遡ってデータが取得できたと思います。詳細はドキュメント(英語)を見てご確認いただければと思います。
      Document : https://keepa.com/#!api の DOCUMENTATION

  4. fuku より:

    すみません投稿出来ていなかったようなので再投稿致します。
    記事を参考に初期セットアップをして、「Access Token 取得関数」までは上手くいっております。

    ただ、「getCatalogItem」の関数でつまづいてしまっております。
    実行しても結果が表示されません。
    サンプルプログラムとサンプル結果を比較すると、プログラムの方に「=== Response 詳細 ===」の記載がないのですが、サンプルプログラム途中で切れてしまっていないでしょうか?
    お忙しいところお手数ですがご確認頂ければ幸いです。

    わたくしの環境で実行すると下記結果となります。
    returnではなくprintにするとresponse 200で返ってきてるので、エラーは起きてないように思えます。
    URLもサンプルの実行結果と同じでした。

    ================================================

    Function : SPAPI_GetCatalogItemsForASIN
    === Request ===
    Request URL = https://sellingpartnerapi-fe.amazon.com/catalog/2020-12-01/items/B07WXL5YPW?includedData=identifiers%2Cimages%2CproductTypes%2CsalesRanks%2Csummaries%2Cvariations&marketplaceIds=A1VC38T7YXB528

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      fuku さま
      ブログへのコメントありがとうございます。反応が遅くなってしまいました。

       

      ご指摘いただきましたポイントですが、表示する部分まで記載していませんでした。(後ほど修正したいと思います。)
      取り急ぎ、以下の形で記載すれば内容が確認できると思います。

       

      print('=== Response detail - SPAPI_GetCatalogItemsForASIN ===')
      print('Response Status : ' + str(api_response.status_code))
      print('Response headers :\r\n' + str(api_response.headers))
      print('Response json :\r\n' + str(response_json))

  5. fuku より:

    ありがとうございます!
    また、二重投稿になっていたようで大変申し訳ありません。
    古い方は削除頂ければと思います。

    早速トライしてみようと思うのですが、下記で「response_json」の定義エラーになっているようでした。
    お手隙の際にご確認頂けますでしょうか。

    よろしくお願い致します。

    ------------------

    print('Response json :\r\n' + str(response_json))

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      またまた抜けてました。
      こちらでいけると思います。

       

      ## レスポンスをdict形式に変換
      response_dict = json.loads(api_response.text)
      ## 見やすく表示する用
      response_json = json.dumps(response_dict, indent=4)
      print('=== Response detail - SPAPI_GetCatalogItemsForASIN ===')
      print('Response Status : ' + str(api_response.status_code))
      print('Response headers :\r\n' + str(api_response.headers))
      print('Response json :\r\n' + str(response_json))

       

      開発、がんばってください!

  6. ヤマグチ より:

    初めましてコメント失礼致します。
    追記の

    ## レスポンスをdict形式に変換
    response_dict = json.loads(api_response.text)
    ## 見やすく表示する用
    response_json = json.dumps(response_dict, indent=4)
    print('=== Response detail - SPAPI_GetCatalogItemsForASIN ===')
    print('Response Status : ' + str(api_response.status_code))
    print('Response headers :\r\n' + str(api_response.headers))
    print('Response json :\r\n' + str(response_json))

    部分はどこに配置すればよろしいでしょうか。

    超初心者から始めてます、ご教授よろしくお願いいたします。

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      ブログへの訪問ありがとうございます。

      表示するためには、「api_response」にSP-APIから取得した結果が含まれている必要があります。

      配置する場合は、apiの応答結果が変数に格納されている場所(=SP-APIへの問合せを実行し、情報取得が完了してる場所)の後に配置する必要があります。
      なので、今回のサンプルプログラムでいうと
      「api_response = requests.get(request_url, headers=headers)」の後ろ、かつ、return の前に配置する
      もしくは return で戻る関数の後ろ(関数の戻り値を変数「api_response」に格納する部分の後ろ)あたりに
      配置すればSP-APIから取得したデータの内容確認が出来るようになる形です。

      超初心者の方に役立つのは大変うれしいです。
      最初は中々てこずると思いますが、がんばってください!応援してます。

  7. ヤマグチ より:

    早々の返信ありがとうございます。
    無事サイトどうりの結果が出力されました。
    ありがとうございます。

  8. ハッちゃん より:

    初めまして。初心者です。過去に楽天、ebayのapiは触ったことがありますがamazon苦戦中です。

    SPAPI_GetCatalogItemsForASINで
    "errors": [
    {
    "message": "Access to requested resource is denied.",
    "code": "Unauthorized",
    "details": ""
    }
    ]

    が発生します。アドバイスいただけたら嬉しいです。

    Amazon MWS から SP-API への移行 [準備編]
    に従った後、このページの内容を実行。
    具体的には下記のようなコードにしました。
    SPAPI_Get_Tokenの関数中に
    global resp_refresh_token
    を追記。
    SPAPI_Get_Token関数を閉じた下に
    SPAPI_LWA_Client_ID =***
    SPAPI_LWA_Client_PW =***
    SPAPI_Refresh_Token =***
    SPAPI_Access_Token_Endpoint ="https://api.amazon.com/auth/o2/token"
    SPAPI_Get_Token(SPAPI_LWA_Client_ID, SPAPI_LWA_Client_PW, SPAPI_Refresh_Token, SPAPI_Access_Token_Endpoint)

    その下に
    SPAPI_GetCatalogItemsForASIN関数を定義

    その下に下記を記載
    Asin_Code ="B0B5FDSHBQ"
    SPAPI_Access_Token = resp_access_token
    SPAPI_IAM_User_Access_Key =***
    SPAPI_IAM_User_Secret_Key = ***
    SPAPI_Method ="GET"
    SPAPI_Service ="execute-api"
    SPAPI_Domain = "sellingpartnerapi-fe.amazon.com"
    SPAPI_MarketplaceId = "ATVPDKIKX0DER"
    SPAPI_Region = "us-west-2"
    SPAPI_Endpoint = "https://sellingpartnerapi-fe.amazon.com"
    SPAPI_SignatureMethod ="AWS4-HMAC-SHA256"
    SPAPI_UserAgent ="Zats-SPAPI-App/Ver1.0 (Tool=Postman;Platform=Windows10)"

    SPAPI_GetCatalogItemsForASIN(Asin_Code, SPAPI_Access_Token, SPAPI_IAM_User_Access_Key, SPAPI_IAM_User_Secret_Key, SPAPI_Method, SPAPI_Service, SPAPI_Domain, SPAPI_MarketplaceId, SPAPI_Region, SPAPI_Endpoint, SPAPI_SignatureMethod, SPAPI_UserAgent)

    • 山梨_金峰山_ジャンプ Sovayanagi より:

      ブログへの訪問ありがとうございます。
      いただいたエラーは、エラー内容から原因を特定する事が非常に難しいため、何パターンかの切り分けが必要になります。
      切り分けをする上で、まずは現在お使いのAPIアクセス用アカウントが問題ないかをご確認いただく形が良いかと思います。

      私が書いた別記事「Amazon MWS から SP-API への移行 [Postmanによるテスト接続編]」を参考にしていただき
      APIへ問題なくアクセスできることをご確認いただければと思います。

      もしAPIアクセス用のアカウントに間違いがない、ということであれば
      プログラムの記載のどちらかにエラーがあるのではないか、という切り分け結果になるかと思います。

      • ハッちゃん より:

        ありがとうございます!
        Postman試してみます!

      • ハッちゃん より:

        Postman試してみましたが、やはり同様にUnauthorizedが出ました。
        念の為もう一度確認してみましたが
        Amazon MWS から SP-API への移行 [準備編]
        に記載通りの設定はできているようでした。
        他に考えられる要因はあるでしょうか?

        • 山梨_金峰山_ジャンプ Sovayanagi より:

          Postmanで上手く情報が取得できない、という状況であれば
          ご準備されているSP-API側のアカウント設定が上手くいっていないことになるかと思います。
          切り分けできてよかったです。

          解決に向けては、SP-API側のアカウント設定の見直しを実施いただく形になると思います。
          (何をどうすればいいのか?についてはサポートできなさそうです。)

          解決できない場合は、amazonの開発者サポート窓口にお問い合わせください。

  9. ネコヤナギ より:

    サンプルコードで情報が取得することができました。
    ありがとうございます。

    サンプルコードとドキュメントを読み込み内容の理解を深めてから、実際に目的の情報が取得できるように開発に取り組みたいと思います。

  10. TEL より:

    詳しい説明ありがとうございました!

    GET /catalog/2022-04-01/items
    Operation: searchCatalogItems

    サンプルコードを少し改変して、3辺サイズの取得に成功しました!

    本当に助かりました(*^-^*)

関連キーワード

この記事が気に入ったら
フォローしよう

最新情報をお届けします

Twitterでフォローしよう

おすすめの記事