SEOのためのサーバーログ分析ガイド
クロールログの分析方法を解説します。対象範囲を保ち、ボットの動きを検索順位やトラフィックの話と切り分けて、技術的な修正の優先度を決めます。
ログを分析する理由
Google Search Consoleで見られるのは、3日遅れの集計データだけです。Screaming Frogが再現するのはブラウザーの動きで、Googlebotではありません。検索ボットの実際のリクエストを1件ずつ記録しているのは、Webサーバーのログファイルだけです。正確なタイムスタンプ、URL、レスポンスのステータス、クローラーのIPアドレスが残ります。
ログ分析は、ほかの方法では分からないことに答えを出します。Googlebotが1時間ごとにクロールするページと、数か月訪れていないページ。クローラーが404や500に遭遇する場所。無限のリダイレクトループの有無。パラメーター付きの重複ページやログイン必須のページにバジェットが使われていないか。クロールバジェットの管理を判断するには、こうしたデータが欠かせません。
ログ分析で得られるもの
実際のリクエスト
クローラーからのHTTPリクエストはすべてログに記録されます。サンプリングも集計の遅れもありません
時刻の精度
秒単位のタイムスタンプで、曜日や時間帯ごとのクロールパターンを追えます
1つのログに複数のボット
Googlebot、Bingbot、Yandexなど、すべてのクローラーが1つのファイルに入り、まとめて比較できます
データの遅延
ログはすぐに使えます。再クロールやGSCレポートの更新を待つ必要はありません
ログファイルの入手方法
ログの場所は、Webサーバーとホスティング事業者によって異なります。多くのVPSや専用サーバーでは、SSHでログファイルに直接アクセスできます。分析には、通常、直近30〜90日分のアクセスログが必要です。この期間なら、季節による変動が分かり、データも古くなりません。
| サーバー/プラットフォーム | ログの標準パス | 備考 |
|---|---|---|
| Nginx | /var/log/nginx/access.log | logrotateでローテーションされます。過去分はaccess.log.1、access.log.2.gzなどに保存されます |
| Apache | /var/log/apache2/access.log(Debian/Ubuntu)、/var/log/httpd/access_log(RHEL) | 形式はCLFまたはCombinedです。LogFormatディレクティブで確認します |
| cPanel / WHM | ~/access-logs/<domain>、またはFile Manager → Logs | ドメインごとに分かれていることが多く、cPanelの画面からRaw Accessも使えます |
| Cloudflare Workers / Enterprise | Logpush API → S3, R2, GCS | Enterpriseプランのみ。Free/Proの場合はWorkers Analytics Engineを使います |
| AWS CloudFront | ディストリビューションの設定 → LoggingでS3バケットを指定します | 5〜10分ごとに出力され、gzipで圧縮されます |
| Google Cloud / GCS | Cloud Logging → BigQueryまたはGCSにエクスポート | 大量のデータ向きです。BigQueryでSQLを直接実行できます |
# Nginx: view the last 1000 lines of the access log
tail -n 1000 /var/log/nginx/access.log
# Size of the current log file
du -sh /var/log/nginx/access.log
# Decompress and merge rotated logs
zcat /var/log/nginx/access.log.*.gz | cat - /var/log/nginx/access.log > all_access.log
# Line count (≈ number of requests) in the merged file
wc -l all_access.log/etc/logrotate.d/nginxのrotate 30を事前に増やしてください。削除されたログは復元できません。ログの構造:CLF形式
多くのサーバーは、標準でCombined Log Format(CLF)を使います。Common Log Formatを拡張した形式です。SEO分析で重要になるフィールドは次のとおりです。
# Combined Log Format record (Nginx/Apache)
66.249.66.1 - - [19/May/2026:14:32:01 +0000] "GET /blog/seo-guide/ HTTP/1.1" 200 45231 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ └─ User-Agent
│ │ │ │ │ │ │ └───── Referer
│ │ │ │ │ │ └─────────── Bytes sent
│ │ │ │ │ └──────────────── HTTP status
│ │ │ │ └─────────────────────────────────────────── Request
│ │ │ └────────────────────────────────────────────────────────────────────────── Timestamp
│ │ └───────────────────────────────────────────────────────────────────────────── Auth user
│ └─────────────────────────────────────────────────────────────────────────────── Ident
└─────────────────────────────────────────────────────────────────────────────────────────── IP address| フィールド | SEOでの重要度 | 見るポイント |
|---|---|---|
| IPアドレス | 高 | Googlebot、Bingbot、YandexのIP範囲。本物のクローラーの絞り込みに使います |
| タイムスタンプ | 高 | クロール頻度と、特定のURLへの最終訪問時刻 |
| リクエスト(メソッド+URL) | 最重要 | どのURLがクロールされているか。必要なページ、重複、パラメーター付きURL、存在しないパス |
| HTTPステータス | 最重要 | 200(正常)、301/302(リダイレクト)、404(リンク切れ)、500(サーバーエラー) |
| 送信バイト数 | 中 | 極端に小さいサイズは、空のページや仮のレスポンスのサインです |
| ユーザーエージェント | 最重要 | Googlebotを、ほかのボットや実際のユーザーと区別します |
フィルタリング:クローラーの抽出
生のログには、ユーザーのリクエスト、監視用のping、スパムボット、検索クローラーが混ざっています。SEO分析で必要なのは、検索ロボットだけです。最も確実なのは、ユーザーエージェントの文字列で絞り込み、そのあとDNSでIPを検証する方法です。
# Extract all Googlebot requests
grep -i 'googlebot' /var/log/nginx/access.log > googlebot.log
# Extract all SEO crawlers
grep -iE '(googlebot|bingbot|yandex|ahrefsbot|semrushbot|mj12bot)' \
/var/log/nginx/access.log > all_bots.log
# Count requests by crawler
grep -oiE '(googlebot|bingbot|yandexbot|ahrefsbot|semrushbot)' \
/var/log/nginx/access.log | sort | uniq -c | sort -rn
# Verify IP via reverse DNS (confirm it's the real Googlebot)
host 66.249.66.1
# Should return: crawl-66-249-66-1.googlebot.com
# Then forward DNS:
host crawl-66-249-66-1.googlebot.com
# Should return the same IP — then it's a legitimate GooglebotGooglebotの文字列を偽装することがよくあります。正確に絞り込むには、逆引きDNSでIPを検証します。本物のGooglebotは*.googlebot.comに解決されます。GoogleはIP範囲を、Special IP Addresses APIで公式に公開しています。SEOで見る主な指標
絞り込んだら、分析に進みます。手間が少なく、得られる知見が多い指標は次の6つです。
期間中にGooglebotが特定のURLを訪れた回数です。PageRankが高いページや更新頻度の高いページは、よくクロールされます。重要なページが30日間で1回しか訪問されていなければ、Googleは価値が低いと見ています。
目標:主要ページは3日に1回以上Googlebotのリクエストに占める4xxと5xxの割合です。404はクロールバジェットを無駄にします。500はシステム全体の問題を示します。エラー率が高いと、サイトに対するGoogleの信頼が下がります。
基準:4xxは3%未満、5xxは0.5%未満Googlebotのリクエストのうち、301または302で終わるものの割合です。リダイレクトはバジェットを消費し、再インデックス登録を遅らせます。特にリダイレクトチェーン(A → B → C)は悪影響が大きくなります。
基準:3xxはボットの全リクエストの10%未満同じコンテンツが異なるURLで存在するケースです。wwwの有無、末尾スラッシュの有無、UTMパラメーターの有無などがあります。それぞれ別々にクロールされるため、クロールバジェットがそのまま流出します。
目標:コンテンツ1つにつき正規URLを1つに30日間、Googlebotが一度もリクエストしなかった主要ページ(カテゴリ、ランディングページ、新着記事)です。内部リンクの問題か、robots.txtによるブロックが疑われます。
目標:30日間クロールされない重要ページを0件にGoogleがクロールすべきでないページです。管理画面、セッションページ、テスト環境、パラメーター付きの重複ページなどがあります。バジェットを無駄にし、セキュリティ上のリスクになることもあります。
目標:GooglebotのログにセンシティブなURLを0件に分析ツール
ログ分析の作業の95%は、3つのツールでカバーできます。手早い確認にはコマンドライン、詳しい分析には専用のGUIツール、大量のデータや自動化にはPythonとBigQueryです。
Bash:インストール不要の手早い分析
# Top 20 URLs Googlebot crawls most often
grep -i 'googlebot' access.log \
| awk '{print $7}' \
| sort | uniq -c | sort -rn | head -20
# Response status distribution for Googlebot
grep -i 'googlebot' access.log \
| awk '{print $9}' \
| sort | uniq -c | sort -rn
# URLs returning 404 to Googlebot
grep -i 'googlebot' access.log \
| awk '$9 == 404 {print $7}' \
| sort | uniq -c | sort -rn | head -50
# Googlebot request count by day
grep -i 'googlebot' access.log \
| awk '{print $4}' \
| cut -d: -f1 | tr -d '[' \
| sort | uniq -c
# Parametric URLs in Googlebot requests
grep -i 'googlebot' access.log \
| awk '{print $7}' \
| grep '?' \
| sort | uniq -c | sort -rn | head -30Screaming Frog Log File Analyser
有料のツール(年額$259)ですが、定期的な分析には欠かせません。ログファイルを読み込んで解析し、ボットとブラウザーの区分け、ステータスのダッシュボード、ディレクトリ単位のクロールのヒートマップ、クロールされていないページの一覧といったレポートを作ります。Nginx、Apache、IIS、CloudFlare、Fastly、独自のCSV形式に対応しています。
Python:大きなファイル向けの柔軟な分析
import re
from collections import Counter
LOG_PATTERN = re.compile(
r'(?P<ip>\S+) \S+ \S+ \[(?P<time>[^\]]+)\] '
r'"(?P<method>\S+) (?P<url>\S+) \S+" '
r'(?P<status>\d{3}) (?P<size>\S+) '
r'"(?P<referer>[^"]*)" "(?P<ua>[^"]*)')
def parse_log(path: str, bot_pattern: str = 'googlebot') -> list[dict]:
entries = []
with open(path) as f:
for line in f:
m = LOG_PATTERN.match(line)
if not m:
continue
if bot_pattern.lower() not in m.group('ua').lower():
continue
entries.append({
'ip': m.group('ip'),
'url': m.group('url'),
'status': int(m.group('status')),
'ua': m.group('ua'),
})
return entries
entries = parse_log('access.log')
# Top 20 URLs by crawl frequency
url_counts = Counter(e['url'] for e in entries)
for url, count in url_counts.most_common(20):
print(f'{count:>6} {url}')
# 404 errors
errors = [e['url'] for e in entries if e['status'] == 404]
for url, count in Counter(errors).most_common(20):
print(f'{count:>6} 404 {url}')クロールパターン:何を見るか
数値は、読み解かなければ意味がありません。Googlebotのログでは、次のようなパターンを探します。
パターン1:クロールされているのにインデックス登録されない
Googlebotが定期的に訪れているのに、GSCで「インデックス登録済み」にならないケースです。原因は、noindexのメタタグ、HTTPヘッダーのX-Robots-Tagによるブロック、内容の薄いコンテンツ、別ページを指すcanonicalタグなどです。定期的にクロールされているURLの一覧と、GSC APIで取得したインデックス登録済みのページを突き合わせると、差分から問題のページが見つかります。
パターン2:クロールの急増
短時間にGooglebotのリクエストが急増するのは、URLが無限に生成されているサインであることが多くなります。ファセット、パラメーター付きのページネーションURL、URLに含まれるセッショントークンなどが原因です。クロールの急増は、数時間でバジェットを使い切り、サーバーにも実際の負荷をかけます。リクエストを1時間ごとのヒストグラムにすると、異常なピークがすぐに見つかります。
パターン3:新しいページが無視される
3週間前に作った新しいページをサイトマップに追加したのに、ログにGooglebotのリクエストが1件もないケースです。原因は、そのページへの内部リンクがない、ボットがサイトマップを再クロールしていない、階層が深すぎる、のいずれかです。新しいURLはGSCのURL検査ツールで確認し、ログで初めて現れた日付を調べます。
パターン4:レンダリングを妨げるリソース
Googlebotは、HTMLのページだけでなく、CSS、JS、画像もリクエストします。重要なリソースがrobots.txtでブロックされていると、ボットはページをレンダリングできず、評価が下がるおそれがあります。ログで、Googlebotのリクエストのうち静的リソースが占める割合と、必要なJSファイルがブロックされていないかを確認します。
よくある問題と対処法
| ログで見つかる問題 | 原因 | 対処法 |
|---|---|---|
| Googlebotへの404が多い | 削除したページに、外部リンクや内部リンクが残っている | 最も近い公開中のページへ301リダイレクトし、リンク切れの内部リンクを削除する |
| パラメーター付きURLがクロールされている | UTMタグ、並び替え、セッションがrobots.txtでブロックされていない | robots.txtでDisallowし、ページ側ではパラメーターなしのURLをcanonicalタグで指定する |
| リダイレクトチェーン(A→B→C) | サイト構造の変更後にリダイレクトが積み重なった | 1回の転送にまとめ、リンク元をすべて更新する |
| ログに/admin、/stagingのページがある | 管理用のセクションがブロックされていない | robots.txtで/admin/をDisallowし、ステージングにはHTTP認証をかける |
| Googlebotへの5xxレスポンス | アクセスのピーク時にサーバーが過負荷になっている、またはバックエンドでエラーが起きている | TTFBを改善し、キャッシュを追加し、クローラーのレート制限を設定する |
| 重要なページがクロールされない | 内部リンクがない、階層が深すぎる、サイトマップにない | サイトマップに追加し、主要ページから内部リンクを張る |
| wwwあり/なしの重複 | 正規のドメインへの301リダイレクトが設定されていない | nginxやApacheの設定で、wwwなしからwwwあり(またはその逆)へ301リダイレクトする |
| robots.txtが必要なJS/CSSをブロックしている | テンプレートの設定で/assets/や/static/がDisallowになっている | レンダリングに必要な重要リソースのブロックを外す |
# Detect redirect chains in logs
# Step 1: extract all URLs with 301/302 status for Googlebot
grep -i 'googlebot' access.log \
| awk '$9 ~ /^30[12]$/ {print $7}' | sort -u > redirects.txt
# Step 2: check if any of those URLs are also redirect sources
while read url; do
if grep -q "GET $url " redirects.txt 2>/dev/null; then
echo "CHAIN: $url"
fi
done < redirects.txt
# Find 5xx errors grouped by URL and hour
grep -i 'googlebot' access.log \
| awk '$9 ~ /^5/ {print $4" "$7}' \
| cut -d: -f1-2 \
| sort | uniq -c | sort -rn | head -20FAQ
まとめ
ログ分析は、最も正直なSEO監査です。GSCが示すのは集計値で、Screaming Frogは動きを再現するだけですが、ログにはGooglebotの実際の動きがすべて残っています。手順はシンプルです。30〜90日分のログを入手する → ユーザーエージェントとDNS検証でクローラーを絞り込む → 6つの主要指標を計算する → GSCのインデックスと突き合わせる → 差分を修正する。
まずは3つのBashコマンドから始めます。クロール数の多い上位20URL、ステータスコードの分布、404の上位です。1時間もあれば、設定するリダイレクト、robots.txtでブロックするURL、サイトマップに追加するページといった具体的な作業リストができます。有料の監査より速く、安く済みます。データはすでにサーバーにあります。
ログ分析はどのくらいの頻度で行うべきですか?
サイトが小規模(500ページ未満)でもログは必要ですか?
本物のGooglebotと偽物はどう見分けますか?
クロール頻度は検索順位に直接影響しますか?
Googlebotのクロールが激しすぎて、サーバーに負荷がかかっている場合はどうしますか?
Check it with SpiderHead
Free and local: run the audit on your own machine.



