2026年5月20日
2026年5月20日
WordPressのページのリンク切れを検出する方法
はじめに
リンク切れ(404エラー)はSEOと UXの両方に悪影響を与えます。内部リンクが切れると検索エンジンのクロールが滞り、外部リンク切れはユーザー体験を損ないます。定期的な検出・修正がサイト品質の維持に不可欠です。
症状・原因
- Google Search Consoleで「404(見つかりません)」のURLが大量に表示されている
- ページを削除・移動したが内部リンクを更新していない
- 外部サイトのURLが変更・削除されて外部リンクが切れている
- リダイレクト設定が不完全でリンクが古いURLのまま
解決手順
ステップ1:Google Search Consoleで404エラーを確認する
Google Search Console での確認手順:
1. Search Console → 「ページ」レポートを開く
2. 「除外」タブ → 「見つかりません(404)」を選択
3. 対象URLリストをCSVでエクスポート
4. 「参照元ページ」列でどのページからリンクされているか確認
また:
カバレッジ → エラー → 「送信済みURL が見つかりません(404)」
→ サイトマップ経由でGoogleに送信された404を特定
ステップ2:プラグインでリンク切れを自動検出する
【Broken Link Checker プラグイン】
管理画面 → ツール → リンクチェッカー
設定:
・リンクの確認間隔: 72時間
・メール通知: 有効
・どのコンテンツをチェック: 投稿・固定ページ・コメント
注意: サーバーリソースを消費するため
本番環境では確認後に無効化推奨
// wp-config.php: Broken Link Checker の負荷を軽減
define('BLC_SAFE_MODE', true); // バックグラウンド処理を制限
// または WP-CLI でリンクチェック(サーバーサイド)
// wp blc postmeta --all ← プラグインがWP-CLI対応の場合
ステップ3:WP-CLIでリンク切れを検出する
# 全投稿の内部リンクを取得してリンク切れチェック
wp post list --post_type=post,page --post_status=publish \
--fields=ID,post_title,guid --format=json > /tmp/posts.json
# 特定ドメインの内部リンクを抽出
wp post list --post_status=publish --format=ids | \
xargs -I{} wp post get {} --field=post_content | \
grep -oP 'href="https?://example\.com[^"]*"' | \
sort -u > /tmp/internal_links.txt
# curlで各リンクのHTTPステータスをチェック
while IFS= read -r url; do
clean_url=$(echo "$url" | sed 's/href="//;s/"//')
status=$(curl -s -o /dev/null -w "%{http_code}" \
--max-time 10 --location "$clean_url")
if [ "$status" = "404" ] || [ "$status" = "410" ]; then
echo "BROKEN [$status]: $clean_url"
fi
done < /tmp/internal_links.txt
# Apacheアクセスログから404を抽出
grep ' 404 ' /var/log/apache2/access.log | \
awk '{print $7}' | sort | uniq -c | sort -rn | head -30
# Nginxアクセスログから404を抽出
grep '"GET.*" 404' /var/log/nginx/access.log | \
awk -F'"' '{print $2}' | awk '{print $2}' | \
sort | uniq -c | sort -rn | head -30
ステップ4:Screaming FrogでサイトをクロールしてリンクチェックするPHP
// functions.php: 404エラーをログに記録するカスタム実装
add_action('wp', function(): void {
if (!is_404()) {
return;
}
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
$referer = $_SERVER['HTTP_REFERER'] ?? '(direct)';
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
// ボットは除外
if (str_contains(strtolower($user_agent), 'bot')) {
return;
}
// データベースに記録
global $wpdb;
$wpdb->insert(
$wpdb->prefix . '404_log',
[
'request_url' => esc_url_raw($request_uri),
'referer' => esc_url_raw($referer),
'created_at' => current_time('mysql'),
]
);
});
// テーブル作成(プラグイン有効化時)
function create_404_log_table(): void {
global $wpdb;
$table = $wpdb->prefix . '404_log';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS {$table} (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
request_url VARCHAR(2048) NOT NULL,
referer VARCHAR(2048) NOT NULL,
created_at DATETIME NOT NULL,
INDEX (created_at)
) {$charset_collate};";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_404_log_table');
ステップ5:定期的な自動リンクチェックを設定する
// functions.php: 週次でリンク切れをメール通知
add_action('wp_scheduled_link_check', 'run_link_check');
function run_link_check(): void {
$posts = get_posts([
'post_type' => ['post', 'page'],
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
]);
$broken = [];
foreach ($posts as $post_id) {
$content = get_post_field('post_content', $post_id);
preg_match_all('/href=["\']([^"\']+)["\']/', $content, $matches);
foreach ($matches[1] as $url) {
if (!str_starts_with($url, 'http')) {
continue;
}
$response = wp_remote_head($url, ['timeout' => 10, 'redirection' => 3]);
$code = wp_remote_retrieve_response_code($response);
if ($code === 404 || $code === 410) {
$broken[] = "Post {$post_id}: [{$code}] {$url}";
}
}
}
if (!empty($broken)) {
wp_mail(
get_option('admin_email'),
'リンク切れ検出レポート',
implode("\n", $broken)
);
}
}
if (!wp_next_scheduled('wp_scheduled_link_check')) {
wp_schedule_event(time(), 'weekly', 'wp_scheduled_link_check');
}
注意事項
- Broken Link Checkerプラグインは便利ですが、サーバーリソースを大量消費することがあります。チェック完了後は無効化するか、スケジュール間隔を長めに設定してください
- 外部リンクのチェックは相手サーバーへのリクエストが多くなりすぎると、アクセス拒否される場合があります。間隔を空けてチェックするようにしてください
- 404ログを蓄積する場合、テーブルサイズが肥大化しないよう定期的に古いレコードを削除してください
まとめ
リンク切れ検出は①Google Search ConsoleのカバレッジレポートでGoogleが検出した404を確認、②Broken Link Checkerプラグインで自動スキャン、③WP-CLIとcurlで内部リンクの一括チェック、④Apacheログから実際のユーザーが踏んだ404を抽出、⑤wp_headのis_404()フックでリアルタイムログ記録、の組み合わせで効率よく把握できます。