AmazonからXMLを取得して商品をページに表示する際、以下の2点で困ってました。
・初期表示時に503エラーになると、手動でデータを消す必要がある
・いつの間にか画像が見つからない状態になる
503エラーになること自体は回避できなかったのですが、今までよりは比較的マシになったので、備忘として書いておきます。
503エラーの件ですが、Amazonサーバーは一秒間に決まった数しか処理できないので、全世界からアクセスされる都合上、避けられないという印象です。
2018/05/16追記
仕様を完全に勘違いしてたんですが、AmazonのAPIは1秒間に1リクエストという制限があるそうです。なお売り上げに応じて最大10リクエストまで増えるようですが、リクエスト数を増やすためには返却値のDetailPageURLをそのまま使わないといけないようです(旧来の短いURLでもアソシエイトの収益は入るものの、リクエスト数増加の判定には使われない模様)。この件についてのさらなる改修は、記事最後の方に追記しました。
PHP上で、503エラーの場合は再度XML取得するように改修したかったのですが、未だにPHP4環境なので、Try Catchが使えず断念しました。
まぁ無限ループになったら怖いし、AmazonのXML取得の規約上やっていいのか判断つかなかったですし(再取得の秒数間違えると、スロットリング制限にかかって面倒くさい事になりそうでした)。
初期表示時に503エラーになったら、XML取得できずに空のデータのままなんですが、そのままDBへINSERTされてしまうのが困りものでした。こうなると手動でDELETEしないと、ずっと商品が表示できなくなります。
503エラーを直接検知する方法が分からなかったので、XMLのタイトルが空だったらエラーだろうということで、下記のように回避しました。
function newData($product) { $this->getAmazonData(&$product, $mode = "new"); //2018.05.11-takehana-add-s if($product[title] == ""){ return; } //2018.05.11-takehana-add-e
こうすれば、初期表示時に503エラーになっても、画面をリロードすればそのうち商品が表示されるようになるので、手動で対応する必要は無くなりました。
一度商品を表示できていても、いつの間にか画像がありません(No-image)状態になってしまうのも困ってました。てっきりAmazonが画像URLを随時変えてるのかと勘違いしていたのですが、ソースみたらAmazonの仕業ではなく自分の勘違いと分かりました。
記事表示が変になるデータを調べてみたら、nucleus_plugin_amazonテーブルの「similar」という項目の中身が文字化けしているのか「??」という文字が頻出していて、見ただけでまともに動きそうにない雰囲気でした。
不正なデータ件数を調べたら数千件あったので、手動でやるのは諦めてSQLで物理削除しました。このあとで記事を再表示すれば、初期表示と同じ状態になってるので、特に問題なく商品が表示されるようになりました。
なんで文字化けデータが入るのか悩んだんですが、情報キャッシュ期間をすぎたあとは、Amazonの規約に従い、ソース上で再度XMLを取得して一部分をUPDATEする仕組みになっているので、この時に運悪く503エラーなどが発生したら、文字化けした内容をそのままUPDATEしてる可能性があると思い、下記のようにプラグインを改修しました。
function updateData($product) { $this->getAmazonData(&$product, $mode = "update"); //2018.05.11-takehana-add-s if($product[title] == ""){ return; } //2018.05.11-takehana-add-e
すでに怪しいデータは全件削除済なので、上記改修の妥当性はまだ未検証なんですが、3ヶ月以上たった記事をアトランダムに表示しても、今のところ問題が無さそうだったので、ひとまず上記改修のまま様子見してみます。
2018/05/16追記
AmazonのAPIの503エラーは数年前に仕様変更になっていて、通常は同じIDだと1秒に1リクエストしか許可しない(503エラーにする)ということのようです。どうも誰か極端にAPIアクセスする割には売上が少ないといった事が続き、それが原因で仕様改定になったようですね。
NP_Amazonの作り的に1回で1リクエストしかAPIアクセスしないので、大量に新規の商品があったら503エラーになってもおかしくないんですが、体感的にはそうでない時も503になるといった印象でした。一度新規表示したらキャッシュしているし、そんなにアクセス数が無いから503エラーが連続するのもおかしい気がします。
とはいえBotとか過去記事にアクセスして、APIへ再取得かけにいってるタイミングとかにあたると503エラーになってもおかしくない気がしました。あと自作ヴィジットを置いてるのでIDが同一だから、誰か悪さしたらアクセス過多になる可能性もあります。
とりあえず自作ヴィジットは不要なものは削除しました。あとはAPIアクセス前に最終アクセス日を確認して、1秒以内だったら1秒待ってから、APIへアクセスするように改修してみました。
そのために以下のような内容の「checkTime.php」を用意して、NucleusプラグインのAmazonフォルダ内に格納しました(文字コードはプラグイン類と合わせておきましょう)。
<?php // 対象ファイル名 $filename = '/var/www/home/*****/nucleus/plugins/amazon/checkTime.php'; // 最終更新日の取得 $mod = filemtime($filename); // 現在日時を取得 $timestamp = time(); // 最終更新日から現在時刻の差を算出 $interval = $timestamp - $mod; if( $interval < '1' ) { // 1秒経っていないなら待機 sleep(1); } // 最終更新日を更新 touch($filename); ?>
あとはNP_Amazonにて、下記のような改修を行いました。
function getAmazonData($product, $mode) { //2018.05.16-takehana-add-s require_once('amazon/checkTime.php'); //2018.05.16-takehana-add-e
これでNP_AmazonからAPIへXML取得する前に、checkTime.phpの最終更新日時を確認して、1秒以内だったら1秒待機してから、XMLを取得するようになりました。
一度に大量の新規商品を記載することがあまりないので、効果の程は何とも言えないところですが、これで少しは503エラーが減ったんじゃないかと思います。
コメント