2026年3月10日
Ken Suzuki
技術

Google Analytics 4 データを Python で自動取得する設定手順

GA4 Data API をサービスアカウント認証で呼び出し、Python スクリプトからアクセス解析データを自動取得・レポート化するまでの手順を解説します。Google Cloud の設定からデータ取得スクリプトの実装まで、実際に動かした手順をまとめています。

Google Analytics 4PythonGA4 APIGoogle Cloud自動化
Google Analytics 4 データを Python で自動取得する設定手順

Google Analytics 4 データを Python で自動取得する設定手順

1. はじめに

Google Analytics 4(GA4)のデータを毎回ブラウザで確認するのは、少し手間がかかりますよね。Python スクリプトから GA4 Data API を呼び出せば、定期的なレポート生成を自動化できます。この記事では、Google Cloud のサービスアカウント設定から Python でのデータ取得まで、実際に動かした手順をまとめています。


2. 全体の流れ

  1. Google Cloud で API を有効化する
  2. サービスアカウントを作成し、認証キー(JSON)を取得する
  3. GA4 プロパティにサービスアカウントを閲覧者として追加する
  4. Python 環境をセットアップしてスクリプトを実行する

3. Google Cloud の設定

3-1. Google Analytics Data API を有効化

  1. Google Cloud Console にアクセスします
  2. 対象プロジェクトを選択します(なければ新規作成)
  3. 上部検索バーに "Google Analytics Data API" と入力します
  4. 「有効にする」 をクリックします

有効化直後はすぐ反映されないことがあります。2〜3分ほど待ってから次のステップへ進んでください。

3-2. サービスアカウントを作成

  1. IAM と管理 → サービスアカウント → サービスアカウントを作成
  2. 名前: ga-report-reader(任意)
  3. ロール: 閲覧者(Viewer)
  4. 作成後、サービスアカウントをクリック → キー → 鍵を追加 → JSON
  5. ダウンロードされた JSON ファイルを安全な場所に保存します
mkdir -p ~/.config
mv ~/Downloads/[ダウンロードしたファイル名].json ~/.config/ga-credentials.json

3-3. GA4 プロパティにサービスアカウントを追加

  1. Google Analytics管理 → プロパティのアクセス管理
  2. 「+」→ ユーザーを追加
  3. サービスアカウントのメールアドレス(ga-report-reader@xxx.iam.gserviceaccount.com)を入力します
  4. 権限: 閲覧者

3-4. プロパティ ID を確認

管理 → プロパティ設定 → プロパティ ID(数字のみ、例: 123456789)をメモしておきます。


4. Python 環境のセットアップ

mkdir ~/ga-reports && cd ~/ga-reports
python3 -m venv venv
source venv/bin/activate
pip install google-analytics-data pandas

5. レポートスクリプト(report.py)

以下が実際に使用しているスクリプトです。ページ別パフォーマンスと流入元の2種類のレポートを CSV に出力します。

"""
GA4 Weekly Report Generator
Google Analytics 自動レポートスクリプト

使い方:
  python report.py

環境変数:
  GA_PROPERTY_ID        : GA4 プロパティID(数字のみ)
  GOOGLE_APPLICATION_CREDENTIALS : サービスアカウント JSON のパス
"""

import os
import csv
from datetime import datetime
from pathlib import Path

from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
    DateRange,
    Dimension,
    Metric,
    OrderBy,
    RunReportRequest,
)

# -----------------------------------------------
# 設定
# -----------------------------------------------
PROPERTY_ID = os.environ.get("GA_PROPERTY_ID", "YOUR_PROPERTY_ID")
DAYS = 30  # 集計期間(日数)
OUTPUT_DIR = Path(__file__).parent / "output"


# -----------------------------------------------
# GA4 データ取得
# -----------------------------------------------
def fetch_report(client, property_id: str, days: int) -> list[dict]:
    """ページ別パフォーマンスレポートを取得する"""
    request = RunReportRequest(
        property=f"properties/{property_id}",
        date_ranges=[DateRange(start_date=f"{days}daysAgo", end_date="today")],
        dimensions=[
            Dimension(name="pagePath"),
            Dimension(name="pageTitle"),
        ],
        metrics=[
            Metric(name="screenPageViews"),
            Metric(name="activeUsers"),
            Metric(name="averageSessionDuration"),
            Metric(name="bounceRate"),
        ],
        order_bys=[
            OrderBy(
                metric=OrderBy.MetricOrderBy(metric_name="screenPageViews"),
                desc=True,
            )
        ],
        limit=50,
    )
    response = client.run_report(request)

    rows = []
    for row in response.rows:
        rows.append(
            {
                "page_path": row.dimension_values[0].value,
                "page_title": row.dimension_values[1].value,
                "views": int(row.metric_values[0].value),
                "active_users": int(row.metric_values[1].value),
                "avg_engagement_sec": round(float(row.metric_values[2].value), 1),
                "bounce_rate": round(float(row.metric_values[3].value) * 100, 1),
            }
        )
    return rows


def fetch_traffic_sources(client, property_id: str, days: int) -> list[dict]:
    """流入元レポートを取得する"""
    request = RunReportRequest(
        property=f"properties/{property_id}",
        date_ranges=[DateRange(start_date=f"{days}daysAgo", end_date="today")],
        dimensions=[
            Dimension(name="sessionDefaultChannelGroup"),
            Dimension(name="sessionSource"),
        ],
        metrics=[
            Metric(name="sessions"),
            Metric(name="activeUsers"),
            Metric(name="bounceRate"),
        ],
        order_bys=[
            OrderBy(
                metric=OrderBy.MetricOrderBy(metric_name="sessions"),
                desc=True,
            )
        ],
        limit=20,
    )
    response = client.run_report(request)

    rows = []
    for row in response.rows:
        rows.append(
            {
                "channel": row.dimension_values[0].value,
                "source": row.dimension_values[1].value,
                "sessions": int(row.metric_values[0].value),
                "active_users": int(row.metric_values[1].value),
                "bounce_rate": round(float(row.metric_values[2].value) * 100, 1),
            }
        )
    return rows


# -----------------------------------------------
# 出力
# -----------------------------------------------
def save_csv(rows: list[dict], filepath: Path) -> None:
    if not rows:
        print(f"  データなし: {filepath.name}")
        return
    with open(filepath, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=rows[0].keys())
        writer.writeheader()
        writer.writerows(rows)
    print(f"  保存: {filepath}")


def print_summary(page_rows: list[dict], source_rows: list[dict]) -> None:
    total_views = sum(r["views"] for r in page_rows)
    total_users = sum(r["active_users"] for r in page_rows)

    print("\n" + "=" * 50)
    print(f"  総ビュー数:         {total_views}")
    print(f"  アクティブユーザー: {total_users}")
    print()

    print("  【ページ TOP5】")
    for r in page_rows[:5]:
        print(
            f"  {r['views']:>3}views  {r['avg_engagement_sec']:>6.1f}s  "
            f"bounce {r['bounce_rate']:>5.1f}%  {r['page_path']}"
        )

    print()
    print("  【流入元 TOP5】")
    for r in source_rows[:5]:
        print(
            f"  {r['sessions']:>3}sessions  {r['channel']} / {r['source']}"
        )
    print("=" * 50 + "\n")


# -----------------------------------------------
# メイン
# -----------------------------------------------
def main():
    if PROPERTY_ID == "YOUR_PROPERTY_ID":
        print("エラー: GA_PROPERTY_ID 環境変数を設定してください")
        print("  例: export GA_PROPERTY_ID=123456789")
        return

    OUTPUT_DIR.mkdir(exist_ok=True)
    date_str = datetime.now().strftime("%Y-%m-%d")

    print(f"\nGA4 レポート生成中... (過去{DAYS}日間)\n")

    client = BetaAnalyticsDataClient()

    print("  ページ別パフォーマンスを取得中...")
    page_rows = fetch_report(client, PROPERTY_ID, DAYS)
    save_csv(page_rows, OUTPUT_DIR / f"{date_str}_pages.csv")

    print("  流入元を取得中...")
    source_rows = fetch_traffic_sources(client, PROPERTY_ID, DAYS)
    save_csv(source_rows, OUTPUT_DIR / f"{date_str}_sources.csv")

    print_summary(page_rows, source_rows)
    print(f"出力先: {OUTPUT_DIR}/")


if __name__ == "__main__":
    main()

6. スクリプトの実行

環境変数を設定してスクリプトを実行します。

export GOOGLE_APPLICATION_CREDENTIALS=~/.config/ga-credentials.json
export GA_PROPERTY_ID=123456789   # 実際のプロパティIDに変更
python report.py

正常に動作すると output/ フォルダに以下の CSV が生成されます:

output/
├── 2026-03-10_pages.csv     # ページ別パフォーマンス(ビュー数・エンゲージメント・直帰率)
└── 2026-03-10_sources.csv   # 流入元(チャネル・セッション数)

7. よくあるエラーと対処

エラー 原因 対処
File ... was not found 認証 JSON のパスが違う GOOGLE_APPLICATION_CREDENTIALS のパスを確認してください
403 PERMISSION_DENIED (SERVICE_DISABLED) API が有効化されていない Cloud Console で API を有効化し、数分待ちます
403 PERMISSION_DENIED (USER_PERMISSION_DENIED) GA4 にサービスアカウントが追加されていない GA4 のアクセス管理でサービスアカウントを閲覧者として追加してください

8. まとめ

Google Cloud のサービスアカウントさえ設定してしまえば、あとはスクリプト1本で GA4 のデータを自動取得できます。取得した CSV を定期的に AI に渡して分析するフローも組みやすく、cron での月次自動化まで設定しておけばほぼメンテナンスフリーで運用できます。

Google Analytics 4 データを Python で自動取得する設定手順 | Shirokuma.online