【Amazon PA-API 】SDKを利用し商品データを取得・出力する例|PHP・WordPress
Amazonアソシエイトでは、Amazon内の商品データを扱えるPA-API(Product Advertising API)を提供しています。
今回は、そのPA-APIを使用しWordPressでAmazonの商品データを取得し出力する例となります。
【Amazon PA-API】SDKを利用し商品データを取得・出力する例
PA-APIのバージョンについて
PA-APIのバージョン4.0を利用できるのが2020年2月11日までとなり、それ以降はバージョン5.0を利用する必要があります。
そのため、このページでもPA-APIのバージョン4.0から、5.0を利用する方法に修正しました。
PA-APIを使用するために必要な情報
まずは、AmazonのPA-APIを使用するために必要な以下の情報を用意します。
- アクセスキーID
- シークレットキー
- アソシエイトタグ
上記、3つの情報を確認する方法については、以下のリンク先を参考にしてみてください。
SDKの利用
PA-APIのバージョン5.0からSDKを利用することができ、それにより、リクエストに必要な署名を自ら作成する必要がなくなったり、例外処理の実装などを簡単に行えます。
今回の例では、PHPのSDKを利用するため、以下のページ内から「paapi5-php-sdk」のzipファイルをダウンロードし解凍し、WordPressの任意のディレクトリへ配置します。
Using SDK · Product Advertising API 5.0
※SDK内のREADMEファイルにはComposerでのインストール方法も掲載されていて試してみましたが、ライブラリが見つからずインストールできませんでした。
SDKを利用しない場合
SDKを利用しない実装も可能ですので、詳しくは以下のリンク先を参考にしてみてください。
Without SDK · Product Advertising API 5.0
PA-APIを利用しAmazonの商品データを取得・出力する例
例では、WordPressでPA-APIを使い、指定したASIN番号の次の商品データを表示します。
- タイトル
- 画像
- 価格
- 商品へのリンク
ソースコードの例は以下となり、商品データを出力したい箇所に記述します。
また、SDKを利用するために、ソースコード12行目のrequire文でSDK内のautoload.phpを読み込んでいますが、パスはSDKを配置した場所によって異なるので、自身のautoload.phpのパスを確認して指定します。
<?php
// SDKを利用するためautoload.phpを読み込み
require_once(get_template_directory() . '/vendor/autoload.php');
// 利用するSDKのクラスをインポート
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi;
use Amazon\ProductAdvertisingAPI\v1\ApiException;
use Amazon\ProductAdvertisingAPI\v1\Configuration;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException;
// 基本のリクエストパラメータを設定するConfigurationのインスタンスを作成
$config = new Configuration();
$config->setAccessKey('XXXXXXXX'); // アクセスキーIDを指定
$config->setSecretKey('XXXXXXXX'); // シークレットキーを指定
$config->setHost('webservices.amazon.co.jp'); // Hostを指定
$config->setRegion('us-west-2'); // Regionを指定
// PA-APIのリクエストを行うDefaultApiのインスタンスを作成
$apiInstance = new DefaultApi(
new \GuzzleHttp\Client(),
$config
);
// GetItemsオペレーションを利用するため、GetItemsRequestのインスタンスを作成
$getItemsRequest = new GetItemsRequest();
$getItemsRequest->setPartnerTag('XXXXXXXX'); // アソシエイトタグを指定
$getItemsRequest->setPartnerType(PartnerType::ASSOCIATES); // PartnerTypeを指定
$itemIds = array(
"XXXXXXXX",
"XXXXXXXX"
);
$getItemsRequest->setItemIds($itemIds); // 取得する商品のASIN番号を指定
$resources = array(
GetItemsResource::ITEM_INFOTITLE,
GetItemsResource::OFFERSLISTINGSPRICE,
GetItemsResource::IMAGESPRIMARYMEDIUM
);
$getItemsRequest->setResources($resources); // 取得したいレスポンスデータによってリソースを指定
// GetItemsRequestのインスタンスに指定したリクエストパラメータが無効の場合にエラーを出力
$invalidPropertyList = $getItemsRequest->listInvalidProperties();
$length = count($invalidPropertyList);
if ($length > 0) {
echo "Error forming the request", PHP_EOL;
foreach ($invalidPropertyList as $invalidProperty) {
echo $invalidProperty, PHP_EOL;
}
return;
}
// ASIN番号をもとに、取得したレスポンスデータをマッピングする関数
function parseResponse($items){
$mappedResponse = array();
foreach ($items as $item) {
$mappedResponse[$item->getASIN()] = $item;
}
return $mappedResponse;
}
try {
// APIリクエストを送信してレスポンスデータを取得
$getItemsResponse = $apiInstance->getItems($getItemsRequest);
if ($getItemsResponse->getItemsResult()->getItems() != null) {
// ASIN番号をもとに、取得したレスポンスデータをマッピング
$responseList = parseResponse($getItemsResponse->getItemsResult()->getItems());
// 商品ごとにデータを出力
foreach ($itemIds as $itemId) {
$item = $responseList[$itemId];
if ($item != null) {
// 商品データを取得
$title = $item->getItemInfo()->getTitle()->getDisplayValue();
$page_url = $item->getDetailPageURL();
$image_url = $item->getImages()->getPrimary()->getMedium()->getURL();
$price = $item->getOffers()->getListings()[0]->getPrice()->getDisplayAmount();
// 商品データを出力
echo "<a href='" . esc_url($page_url) . "' target='blank' rel='nofollow'>";
echo '<p>' . esc_html($title) . '</p>';
echo "<img src='" . esc_url($image_url) . "' alt='" . esc_attr($title) . "'>";
echo '<p>' . esc_html($price) . '</p>';
echo '</a>';
} else {
echo "<p>商品が見つかりません</p>";
}
}
}
if ($getItemsResponse->getErrors() != null) {
// 取得したレスポンスデータが無効の場合、エラーを出力
echo PHP_EOL, 'Printing Errors:', PHP_EOL, 'Printing first error object from list of errors', PHP_EOL;
echo 'Error code: ', $getItemsResponse->getErrors()[0]->getCode(), PHP_EOL;
echo 'Error message: ', $getItemsResponse->getErrors()[0]->getMessage(), PHP_EOL;
}
} catch (ApiException $exception) {
// PA-APIのリクエストがエラーの場合、エラーを出力
echo "Error calling PA-API 5.0!", PHP_EOL;
echo "HTTP Status Code: ", $exception->getCode(), PHP_EOL;
echo "Error Message: ", $exception->getMessage(), PHP_EOL;
if ($exception->getResponseObject() instanceof ProductAdvertisingAPIClientException) {
$errors = $exception->getResponseObject()->getErrors();
foreach ($errors as $error) {
echo "Error Type: ", $error->getCode(), PHP_EOL;
echo "Error Message: ", $error->getMessage(), PHP_EOL;
}
} else {
echo "Error response body: ", $exception->getResponseBody(), PHP_EOL;
}
} catch (Exception $exception) {
// その他のエラーを出力
echo "Error Message: ", $exception->getMessage(), PHP_EOL;
}
?>
APIで取得したデータをキャッシュする場合
上記例の場合、商品データを取得するため、アクセス時に毎回APIリクエストを行いますが、取得したデータをデータベースにキャッシュ(一時保存)することで、APIリクエストの回数を減らすことも可能です。
詳しくは、以下のリンク先を参考にしてみてください。
また、PA-APIのリクエスト回数の上限や利用条件については、以下のリンク先を参考にしてみてください。
ソースコードの説明
以下、例のソースコードのポイントとなる箇所の説明となります。
SDKを利用するための準備
ソースコードの2行目からの以下の箇所では、SDKのクラスのインポートとautoload.phpを読み込み、SDKを利用する準備をしています。
// SDKを利用するためautoload.phpを読み込み
require_once(get_template_directory() . '/vendor/autoload.php');
// 利用するSDKのクラスをインポート
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi;
use Amazon\ProductAdvertisingAPI\v1\ApiException;
use Amazon\ProductAdvertisingAPI\v1\Configuration;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException;
PA-APIのリクエストを行うDefaultApiのインスタンスを作成
ソースコードの14行目からの以下の箇所では、PA-APIのリクエストを行うためのDefaultApiクラスのインスタンスを作成しています。
DefaultApiクラスのインスタンスの引数には、次のインスタンスを指定します。
- 第1引数には、SDKに同梱されているHTTPクライアントGuzzleのClientクラスのインスタンスを指定
- 第2引数には、Configurationクラスのインスタンスを指定
Configurationクラスのインスタンスでは、以下の通りメソッドの引数にリクエストパラメータを指定します。
// 基本のリクエストパラメータを設定するConfigurationのインスタンスを作成
$config = new Configuration();
$config->setAccessKey('XXXXXXXX'); // アクセスキーIDを指定
$config->setSecretKey('XXXXXXXX'); // シークレットキーを指定
$config->setHost('webservices.amazon.co.jp'); // Hostを指定
$config->setRegion('us-west-2'); // Regionを指定
// PA-APIのリクエストを行うDefaultApiのインスタンスを作成
$apiInstance = new DefaultApi(
new \GuzzleHttp\Client(),
$config
);
Configurationインスタンスで指定するリクエストパラメータについて
Configurationインスタンスで指定するリクエストパラメータの「アクセスキーID」「シークレットキー」は、それぞれ自身が発行したものを指定します。
「Host」「Region」は国によって異なりますが、日本のAmazonのデータを取得する場合は上記の通りとなります。
SSL証明書の検証によりAPIリクエストがエラーとなる場合
ローカル環境でテストをする際に、SSL証明書の検証によりAPIリクエストがエラーとなる場合には、Clientクラスのインスタンスの引数に、以下の通りオプションを指定します。
それにより証明書の検証を無効にできます。
new \GuzzleHttp\Client(['verify' => false]),
GetItemsオペレーションを利用
PA-APIは、扱うデータによって種類が分かれ、その種類をオペレーションと呼びます。
今回の例では、商品を識別するASIN番号などをリクエストパラメーターに指定して、商品情報を扱うGetItemsオペレーションを利用します。
SDKで利用する場合には、GetItemsRequestクラスのインスタンスを作成し、リクエストパラメータを以下のようにメソッドの引数で指定します。
例のソースコードでは、27行目からの以下の箇所となります。
// GetItemsオペレーションを利用するため、GetItemsRequestのインスタンスを作成
$getItemsRequest = new GetItemsRequest();
$getItemsRequest->setPartnerTag('XXXXXXXX'); // アソシエイトタグを指定
$getItemsRequest->setPartnerType(PartnerType::ASSOCIATES); // PartnerTypeを指定
$itemIds = array(
"XXXXXXXX",
"XXXXXXXX"
);
$getItemsRequest->setItemIds($itemIds); // 取得する商品のASIN番号を指定
$resources = array(
GetItemsResource::ITEM_INFOTITLE,
GetItemsResource::OFFERSLISTINGSPRICE,
GetItemsResource::IMAGESPRIMARYMEDIUM
);
$getItemsRequest->setResources($resources); // 取得したいレスポンスデータによってリソースを指定
// GetItemsRequestのインスタンスに指定したリクエストパラメータが無効の場合にエラーを出力
$invalidPropertyList = $getItemsRequest->listInvalidProperties();
$length = count($invalidPropertyList);
if ($length > 0) {
echo "Error forming the request", PHP_EOL;
foreach ($invalidPropertyList as $invalidProperty) {
echo $invalidProperty, PHP_EOL;
}
return;
}
オペレーションについて
オペレーションの種類は、PA-APIのバージョン4.0から変更となっています。詳しくは以下のリンク先を参考にしてみてください。
また、オペレーションで共通のリクエストパラメータについては、以下のリンク先を参考にしてみてください。
Common Request Parameters · Product Advertising API 5.0
GetItemsRequestインスタンスで指定するリクエストパラメータについて
GetItemsRequestインスタンスで指定するリクエストパラメータの「アソシエイトタグ」は自身が発行したものを利用し、「PartnerType」は上記の通り指定します。
「ItemIds」は、取得したい商品データのASIN番号を配列で指定します。
「Resources」は、取得するデータの種類を指定するパラメータとなり配列で指定します。(PA-APIのバージョン4.0で「ResponseGroups」によって指定したパラメータの代わりとなります。)
また、オペレーションによってResourcesに指定できる値は異なります。Resourcesの詳細については、以下のリンク先を参考にしてみてください。
Resources · Product Advertising API 5.0
レスポンスデータをASIN番号をもとにマッピングする関数
ソースコードの54行目からの以下の箇所は、レスポンスデータを扱いやすくするため、ASIN番号をもとにマッピングする関数となり、データを出力する際に利用します。
// ASIN番号をもとに、取得したレスポンスデータをマッピングする関数
function parseResponse($items){
$mappedResponse = array();
foreach ($items as $item) {
$mappedResponse[$item->getASIN()] = $item;
}
return $mappedResponse;
}
レスポンスデータを取得し商品データを出力
ソースコードの63行目からの以下の箇所では、取得したレスポンスデータをもとに商品データを出力します。また、取得したレスポンスデータが無効の場合にはエラーを出力します。
try {
// APIリクエストを送信してレスポンスデータを取得
$getItemsResponse = $apiInstance->getItems($getItemsRequest);
if ($getItemsResponse->getItemsResult()->getItems() != null) {
// ASIN番号をもとに、取得したレスポンスデータをマッピング
$responseList = parseResponse($getItemsResponse->getItemsResult()->getItems());
// 商品ごとにデータを出力
foreach ($itemIds as $itemId) {
$item = $responseList[$itemId];
if ($item != null) {
// 商品データを取得
$title = $item->getItemInfo()->getTitle()->getDisplayValue();
$page_url = $item->getDetailPageURL();
$image_url = $item->getImages()->getPrimary()->getMedium()->getURL();
$price = $item->getOffers()->getListings()[0]->getPrice()->getDisplayAmount();
// 商品データを出力
echo "<a href='" . esc_url($page_url) . "' target='blank' rel='nofollow'>";
echo '<p>' . esc_html($title) . '</p>';
echo "<img src='" . esc_url($image_url) . "' alt='" . esc_attr($title) . "'>";
echo '<p>' . esc_html($price) . '</p>';
echo '</a>';
} else {
echo "<p>商品が見つかりません</p>";
}
}
}
if ($getItemsResponse->getErrors() != null) {
// 取得したレスポンスデータが無効の場合、エラーを出力
echo PHP_EOL, 'Printing Errors:', PHP_EOL, 'Printing first error object from list of errors', PHP_EOL;
echo 'Error code: ', $getItemsResponse->getErrors()[0]->getCode(), PHP_EOL;
echo 'Error message: ', $getItemsResponse->getErrors()[0]->getMessage(), PHP_EOL;
}
} catch (ApiException $exception) {
// 以下省略
例外処理
ソースコードの98行目からの以下の箇所は、APIリクエストなどの例外処理を行います。
try {
// 中略
} catch (ApiException $exception) {
// PA-APIのリクエストがエラーの場合、エラーを出力
echo "Error calling PA-API 5.0!", PHP_EOL;
echo "HTTP Status Code: ", $exception->getCode(), PHP_EOL;
echo "Error Message: ", $exception->getMessage(), PHP_EOL;
if ($exception->getResponseObject() instanceof ProductAdvertisingAPIClientException) {
$errors = $exception->getResponseObject()->getErrors();
foreach ($errors as $error) {
echo "Error Type: ", $error->getCode(), PHP_EOL;
echo "Error Message: ", $error->getMessage(), PHP_EOL;
}
} else {
echo "Error response body: ", $exception->getResponseBody(), PHP_EOL;
}
} catch (Exception $exception) {
// その他のエラーを出力
echo "Error Message: ", $exception->getMessage(), PHP_EOL;
}
まとめ
以上がPA-APIを使用し、WordPressでAmazonの商品データを取得し出力する例となります。
また、実際にPA-APIを利用する場合には、関数やクラス内で利用すると便利だと思います。