Amazon のリンクは HEAD ではなく GET で確かめ、403・429・503 は「切れ」ではなく「判定不能」として扱います。 「切れ」と言い切るのは 404 と 410 のときだけにすると、Amazon の bot 対策による誤検知で通知が埋もれません。
解決方法
| 状況 | どうするか |
|---|---|
Amazon 系のホスト(amazon.co.jp・amzn.to・amzn.asia・link.amazon など) |
HEAD は使わず、最初から GET で確かめる |
| それ以外のホストで、HEAD が 2xx・3xx 以外を返した | GET で確かめ直してから判定する |
| 判定 | 2xx・3xx は「OK」、404・410 だけ「切れ」、403・429・503・接続エラーは「判定不能」 |
PHP で書くと、次のような形です(WordPress の外でも動くように curl で書いています)。
// HTTP ステータスから判定する。「切れ」と言い切るのは 404 と 410 だけ
function classify_status(int $code): string {
if ($code >= 200 && $code < 400) return 'ok';
if ($code === 404 || $code === 410) return 'broken';
return 'unknown'; // 403・429・503・接続エラー(0)など
}
function http_status(string $url, bool $head): int {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_NOBODY => $head,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 15,
]);
curl_exec($ch);
return (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
}
function check_link(string $url): string {
$host = parse_url($url, PHP_URL_HOST) ?? '';
// Amazon 系は HEAD を信じない(link.amazon は HEAD に 404 を返す)
$amazon = (bool) preg_match('/(^|\.)(amazon\.co\.jp|amzn\.to|amzn\.asia|link\.amazon)$/', $host);
if (!$amazon) {
$code = http_status($url, true);
if ($code >= 200 && $code < 400) return 'ok';
// HEAD が 2xx・3xx 以外なら、GET で確かめ直す
}
return classify_status(http_status($url, false));
}
手元で動かすと、次のようになりました。
https://link.amazon/B00E5AFZd HEAD=404 GET=302 => ok
https://poco-tech.blog/ HEAD=200 GET=200 => ok
https://poco-tech.blog/no-such-page-xyz/ HEAD=404 GET=404 => broken
起きたこと
自作のアフィリエイト管理のプラグインに、商品のリンクが切れていないかを週に1回確かめる機能を付けました。ところが最初に動かすと、Amazon のリンク14件がすべて「判定不能」になりました。
原因は2つでした。
- 確かめるときの User-Agent が独自の文字列だったので、Amazon が一律で 503 を返していた
- HEAD を断られたら GET でやり直す作りだったが、やり直すのは 405・501 のときだけで、503 ではやり直していなかった
直したあとも、まだおかしなところがありました。Amazon アソシエイトのツールバー(SiteStripe)で作る短縮リンク(link.amazon/…)は、HEAD には 404 を返すのに、GET では正しく転送されます。正しく直したリンクなのに、「切れ」のまま表示されていました。上の結果の1行目がそれです。
判定を3つに分ける理由
Amazon は bot 対策で、403 や 503 を返すことがよくあります。これを「切れ」にすると誤検知だらけになり、通知を見なくなってしまいます。なので、「切れ」と言い切るのは 404 と 410 だけにしました。
判定不能の中でも、Amazon にブロックされたものは一覧の中で折りたたんで表示し、本当のリンク切れが埋もれないようにしています。
User-Agent をブラウザと同じ値にすると、ブロックされにくくなることはあります。ただ、Amazon の利用規約では、データを集めるためのロボットなどの使用は、許諾の範囲に含まれないとされています。この記事では、ブロックを避ける工夫は勧めません。ブロックされたものは「判定不能」として扱い、気になるものだけを手で確かめるのが安全だと思います。
Amazon の API が使えないときも HTTP で確かめる
Amazon の商品情報の API(Creators API)は、直近の売上などの条件を満たさないと 403 を返します。最初はこのとき、Amazon のリンクを全部「判定不能」にしていました。そのせいで、HTTP で確かめれば見つかったはずの 404(実際に2件ありました)まで取りこぼしていました。
API が使えないときは、HTTP での確認に切り替えるようにしました。
確かめた環境
- 2026-08-24 に確認(その後も、
link.amazonの短縮リンクが HEAD に 404、GET に 302 を返すことを確かめています) - 記事のコードは PHP 8.5(curl)で動かしました
- Amazon の側の動きは予告なく変わることがあるので、同じ結果にならないこともあると思います
参考
あわせて読みたい
