GA4とSearch Consoleの数字をPythonで自動取得する|サービスアカウントでの実装手順
毎週ブラウザで管理画面を開いて数字を書き写す作業を、コマンド1つに置き換えました。個人サイトでも15分で組めます。実際に動いているコードをもとに、つまずいた点まで含めて書きます。
結論:ブラウザを開かずに数字が取れる
サイトの数字を確認する作業は、放っておくとだんだんやらなくなります。 管理画面を2つ開いて、期間を選んで、数字を読んで、記録する。1回5分でも、毎週やると面倒になって止まります。
コマンド1つで済むようにすると、続きます。
./.venv/bin/python tools/fetch_metrics.py
これでGA4のセッション数とSearch Consoleの検索クエリが、まとめて手元に出ます。必要なのはサービスアカウント1つだけで、ブラウザでのログインは一度も発生しません。
ログインが不要な点が重要です。定期実行に組み込めるのは、この方式だけです。
使う認証方式:サービスアカウント
Googleの API を使う方法は大きく2つあります。
| 方式 | ブラウザでの許可 | 定期実行 |
|---|---|---|
| OAuth(ユーザー認証) | 毎回または定期的に必要 | 向かない |
| サービスアカウント | 不要 | 向く |
サービスアカウントは「プログラム専用のGoogleアカウント」だと思ってください。メールアドレスの形をした識別子を持ち、そこに閲覧権限を渡すことでデータを読めるようになります。
人間のアカウントとは完全に別物です。 自分のGoogleアカウントに権限があっても、サービスアカウントには何も引き継がれません。ここを勘違いすると、権限エラーの原因が分からなくなります。
鍵ファイルは1か所にだけ置く
サービスアカウントを作ると、JSONの鍵ファイルがダウンロードされます。これは秘密鍵です。
複数のプロジェクトで使う場合、それぞれのフォルダにコピーしてはいけません。 増やすほど流出の面がひろがり、消すときに漏れます。
私は1か所に置いて、各プロジェクトの設定ファイルからパスで参照しています。
SERVICE_ACCOUNT_PATH = "/Users/xxx/keys/reporter.json"
そしてこのパスは、Gitに入れないファイルに書きます。 リポジトリを公開する予定がなくても、最初からこの形にしておくほうが安全です。
準備1:GA4側で権限を渡す
GA4のデータを読むには、サービスアカウントのメールアドレスをプロパティに追加します。
- GA4の「管理」を開く
- プロパティ列の「プロパティのアクセス管理」を選ぶ
- サービスアカウントのメールアドレスを追加し、役割は「閲覧者」にする
アカウント列ではなくプロパティ列です。 上下に似た名前のメニューが並んでいるので間違えやすい場所です。
必要なスコープ
コード側で指定する権限はこれだけです。
https://www.googleapis.com/auth/analytics.readonly
readonly で足ります。 書き込み権限は不要なので、渡さないでください。
準備2:プロパティIDを取り違えない
ここが一番多いつまずきです。
GA4には似て非なる2つのIDがあります。
| 名前 | 見た目 | 用途 |
|---|---|---|
| 測定ID | G-XXXXXXXXXX |
HTMLに埋め込むタグ |
| プロパティID | 551089716 |
APIで指定する |
APIに渡すのは数字のほうです。 G- で始まるIDを入れても動きません。
プロパティIDは「管理 → プロパティの詳細」に数字で表示されています。
実装では、未設定のときに何を見ればいいか出すようにしました。半年後の自分が迷わないためです。
pid = _need("GA4_PROPERTY_ID", C.GA4_PROPERTY_ID,
"GA4の「管理 → プロパティの詳細」に出る数字のIDです(測定IDとは別物)")
準備3:Search Console側で権限を渡す
Search Consoleでも、同じサービスアカウントのメールアドレスをユーザーとして追加します。
- Search Consoleの「設定」→「ユーザーと権限」
- サービスアカウントのメールアドレスを追加
- 権限は「制限付き」で足ります
GA4で権限を渡したから通る、ということはありません。 別のサービスなので、両方で追加が必要です。
スコープはこちらです。
https://www.googleapis.com/auth/webmasters.readonly
実装:GA4のデータを取る
必要なライブラリは2つです。
pip install google-analytics-data google-api-python-client
GA4は専用のクライアントライブラリを使います。
from google.oauth2 import service_account
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
DateRange, Dimension, Metric, RunReportRequest)
creds = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_PATH,
scopes=["https://www.googleapis.com/auth/analytics.readonly"])
client = BetaAnalyticsDataClient(credentials=creds)
req = RunReportRequest(
property=f"properties/{PROPERTY_ID}",
date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")],
dimensions=[Dimension(name="pagePath")],
metrics=[Metric(name="sessions")],
)
res = client.run_report(req)
property の値は properties/551089716 という形式です。数字だけを渡すとエラーになります。
実装:Search Consoleのデータを取る
Search Consoleは汎用のクライアントで叩きます。GA4とは書き方が違います。
from googleapiclient.discovery import build
client = build("searchconsole", "v1",
credentials=creds,
cache_discovery=False)
body = {
"startDate": "2026-08-27",
"endDate": "2026-09-02",
"dimensions": ["query"],
"rowLimit": 25,
}
res = client.searchanalytics().query(siteUrl=SITE_URL, body=body).execute()
cache_discovery=False を付けてください。 付けないと、環境によっては警告が出続けます。
siteUrl の書き方に注意
siteUrl は、Search Consoleに登録したときの表記と完全に一致していなければなりません。
| 登録の種類 | 渡す値 |
|---|---|
| URLプレフィックス | https://example.com/ (末尾のスラッシュまで含む) |
| ドメインプロパティ | sc-domain:example.com |
末尾のスラッシュが1つ違うだけで、権限エラーとして返ってきます。 権限を疑って何度も設定を見直すことになるので、先に表記を確認してください。
つまずいた点:「0件」と「取れていない」を区別する
これが実装で一番重要だった部分です。
登録した直後に動かすと、当然ながらデータは空です。このとき何も表示しないと、動いていないのか、データがまだ無いのかが分かりません。
私は最初これで30分ほど悩みました。接続は成功していたのに、失敗したと思い込んで設定を見直していました。
そこで、次のように分けて表示するようにしました。
接続OK・データ0件(登録直後は反映に2〜3日かかる。異常ではない)
「異常ではない」と書いてあるかどうかで、その後の行動が変わります。 自動化のスクリプトは、成功でも失敗でもない中間の状態を必ず持ちます。 ここを明示しないと、後から自分を疑うことになります。
データが出るまでの時間差
2つのサービスで、反映の速さが違います。
| 反映まで | |
|---|---|
| GA4 | 数分〜数時間 |
| Search Console | 2〜3日 |
Search Consoleの数字は、常に数日前のものです。 昨日公開した記事の検索順位は、今日見ても出てきません。
「登録したのに0件」の相談の多くは、単に反映を待っていないだけです。設定を疑う前に、登録から3日待ってください。
定期実行に組み込む
コマンド1つで動くようになったら、あとは定期実行に載せるだけです。私は週1回、決まった曜日に走らせています。
このとき必ず入れるべきものが1つあります。動かなくなったことを検出する仕組みです。
自動化は壊れても静かに止まります。 通知が来ないことを「正常」と読み違えると、数十日ぶんのデータが欠けます。実際に私は53日間と14日間、止まっていたことに気づきませんでした。
この話は自動化が静かに止まっていた話に詳しく書きました。これから定期実行を組む人は、作る前に読んでおいてください。
よくある質問
サービスアカウントとOAuthはどちらを使うべきですか?
権限を追加したのにエラーになります
GA4のプロパティIDはどこで確認できますか?
データが0件のままです
鍵ファイルはどこに置けばいいですか?
まとめ
- サービスアカウントを使う。 ブラウザ認証が不要で定期実行に載る
- GA4とSearch Consoleの両方で、別々に権限を追加する
- APIに渡すのは数字のプロパティID。 測定ID(G-)ではない
- siteUrlは登録時の表記と完全一致させる。 末尾のスラッシュまで
- 「0件」と「取れていない」を表示で区別する。 ここを省くと自分の設定を疑い続ける
- 反映はSearch Consoleで2〜3日。 待つ前に設定を疑わない
数字を取る作業を自動化すると、見る回数が増えます。 増えた分だけ、次に何を書くかの判断が早くなります。