playpark
ホーム会社概要サービスソリューションブログお知らせ気軽に相談する
playpark

あらゆる仕事を楽しむ

会社概要サービスソリューション気軽に相談する特定商取引法に基づく表記

© 2019-2026 合同会社playpark All Rights Reserved.

  1. ホーム
  2. ブログ
  3. 技術Tips
  4. 【SEO自動化】GA4 × GSC × Google Trendsでコンテンツを自動提案する — エンジニアが作るSEO企画パイプライン
ブログ一覧に戻る
技術Tips

【SEO自動化】GA4 × GSC × Google Trendsでコンテンツを自動提案する — エンジニアが作るSEO企画パイプライン

GA4・GSC・Google Trendsのデータを3段パイプラインで統合し、SEOスコアリングで記事ネタを自動提案するスキル群の設計を解説。マーケ感覚ゼロのエンジニアでも、データが「次に書くべき記事」を教えてくれる仕組みを作りました。

2026年3月25日31分で読める
Claude CodeClaude Code SkillsSEOデータ分析AI開発効率化
【SEO自動化】GA4 × GSC × Google Trendsでコンテンツを自動提案する — エンジニアが作るSEO企画パイプライン

「SEO対策、やらなきゃいけないのは分かってるけど...何から手をつければ?」

キーワード選定、競合調査、検索ボリューム確認、CTR分析。マーケティング担当者なら朝飯前かもしれない。でも、コードは書けるけどマーケは畑違いというエンジニア、少なくないですよね。

「とりあえずブログ書いたけど、誰にも読まれてない」...心当たりありませんか?

私たちもそうでした。技術ブログを書いても検索流入がほぼゼロ。記事のネタ選びは「なんとなく面白そう」という勘頼み。マーケの知識がないなら、データに聞けばいい。エンジニアらしく、SEOをコードで解くことにしました。

この記事で学べること

  • GA4 → Trends → SEO Content Planner の3段パイプラインの全体設計
  • 各ステージで「何のデータをどう変換しているか」の具体的なロジック
  • SEOスコアリング(理論最大130点)の5つの要素と計算式
  • seo-strategyによるコンテンツクラスタ設計とファネル分類
  • blog-seo-improve / blog-schedule-overview による改善・運用サイクル

前提知識

  • Claude Code Skillsの基本概念を把握している
  • Pythonスクリプトの読み書きができる
  • GA4・Google Search Console の基本用語がわかる

この記事で紹介するスキルはすべてGitHubリポジトリで公開しています。

あわせて読みたい

【Claude Code】Agent Teamで複数AIを同時に動かす - バグ調査・コード監査を並列協調で加速する設計
技術Tips20分

【Claude Code】Agent Teamで複数AIを同時に動かす - バグ調査・コード監査を並列協調で加速する設計

Claude CodeのAgent Team機能を活用し、複数の専門AIエージェントが並列で協調するスキル設計を解説。バグ調査・コード監査・インシデント対応の3つの実例から、収束型マルチエージェント協調のパターンを紹介します。

読む

全体像: 3段パイプライン

まず全体のデータフローを俯瞰します。

ga-analyzer ──→ trends-analyzer ──→ seo-content-planner
    │                │                      │
    ▼                ▼                      ▼
 GA4 JSON       Trends JSON          content-strategy.json
 (トラフィック    (キーワード              (SEOスコア付き
  実績データ)     スコアリング)             記事ネタ提案)
                                           │
                            ┌──────────────┼──────────────┐
                            ▼              ▼              ▼
                      seo-strategy   blog-seo-improve  blog-schedule-
                      (クラスタ設計    (CTR/bounce      overview
                       ファネル分類)    自動改善)       (空きスロット検出)

ポイントは各スキルが独立したPythonスクリプトとJSONインターフェースで接続されていること。ga-analyzerの出力JSONをtrends-analyzerがそのまま食べる。trends-analyzerの出力をseo-content-plannerが食べる。UNIXパイプの思想そのものです。

あわせて読みたい

【Claude Code】auto-compact対策 完全ガイド - コンテキスト消失を防ぐ状態管理の設計パターン
技術Tips22分

【Claude Code】auto-compact対策 完全ガイド - コンテキスト消失を防ぐ状態管理の設計パターン

Claude Codeのauto-compactによるコンテキスト消失問題を解決する状態管理設計パターン。kickoff.jsonによる永続化・復帰ポイント設計など、Skills長時間ワークフローを確実に完遂する手法を解説。

読む

ステージ1: ga-analyzer — 「今、何が起きている?」を数値化する

OAuth 2.0でGA4 Data APIに接続

ga-analyzerの核はga_fetch.py。OAuth 2.0クライアント認証でGA4 Data APIからデータを取得します。

python scripts/ga_fetch.py \
  --property-id 123456789 \
  --oauth-client ~/.config/ga4/client_secret.json \
  --output ga_report.json

Service Account認証も対応していますが、個人・チーム利用ならOAuth推奨です(ブラウザでポチッと認証するだけ。JSONキーの管理地獄から解放されます)。

出力される4つの分析軸

ga_report.jsonは4つのセクションを含みます。

セクション中身SEO的な意味
trafficチャネル別セッション数、デバイス比率Organic Search比率30%以上が健全ライン
contentページ別PV、エンゲージメント率人気記事=読者の関心が実証済みの領域
conversionランディングページ × CV高PV×低CV=最優先改善対象
deviceモバイル/PC別の直帰率差ギャップ15pt超は深刻(モバイル最適化必須)

ここで大事なのは、GAデータ単体ではSEOの「次の一手」は見えないということ。GAが教えてくれるのは「今どうなっているか」だけ(健康診断で「太ってますね」と言われても、痩せ方は教えてくれないのと同じ)。「次に何を書けばいいか」は、外部のトレンドデータとの掛け合わせで初めて見えてきます。

ページタイトルからキーワードを自動抽出

ga-analyzerの出力がtrends-analyzerに渡るとき、面白い変換が起きます。ページタイトルからSEOキーワードを自動抽出する処理です。

# 一般的すぎるタイトルを除外
IGNORE_TITLES = {"ブログ", "トップページ", "ホーム", "home", "blog", "404"}

# 【】内のタグをキーワードとして抽出
STRIP_PATTERNS = [
    r"^【(.+?)】",  # 【Claude Code】→ "Claude Code"
    r"^\d+:\s*",
    r"^404:.*$",
]

「ブログ」や「404」はノイズだから捨てる。【】の中身はキーワードとして残す。地味だけど、この前処理の精度がパイプライン全体の品質を左右します(ゴミを入れたらゴミが出てくる、GIGO問題ですね)。

ステージ2: trends-analyzer — 「世の中は今、何に興味がある?」を測る

pytrendsでGoogle Trendsを叩く

trends-analyzerはpytrends(Google Trends非公式API)でトレンドデータを取得します。

# GAレポートからキーワードを自動抽出してTrendsを取得
python scripts/trends_fetch.py \
  --ga-report ga_report.json \
  --output trends_report.json

# 手動でキーワードを指定することも可能
python scripts/trends_fetch.py \
  --keywords "Claude Code,AI開発,LLM活用" \
  --geo JP \
  --output trends_report.json

非公式APIなのでレート制限との戦いが地味につらい。スクリプトにはexponential backoff(20秒→40秒→80秒)のリトライとキャッシュ(24時間有効)を実装しています。pytrendsは1リクエスト最大5キーワードなので、10キーワードなら2バッチ×5秒の待機時間。Googlebot並みにのんびり待ちましょう。

トレンドスコアの3つの軸

trends_report.jsonの各キーワードには3つの指標が付きます。

指標意味SEOアクション
avg_interest(0-100)検索関心度の平均20-50がスイートスポット(競合少×需要あり)
trend_directionrising/stable/decliningrisingなら今すぐ書く。decliningは見送り
rising_queries上昇中の関連クエリ記事の切り口やロングテールKWの宝庫

trend_directionの判定ロジックはシンプルです。

直近1/4期間の平均 vs 全体平均
  → +15%以上 = rising
  → ±15%以内 = stable
  → -15%以下 = declining

「15%」という閾値は感覚で決めたので最適かは分かりません。でも実運用で3ヶ月回してみて、体感として妥当なラインでした(エンジニアの「とりあえず動かしてみよう」精神)。

ステージ3: seo-content-planner — 「次に何を書くべきか」をスコアで出す

ここがパイプラインのクライマックス。GA4実績 × Trendsデータ × GSCデータ × 戦略データの4つのデータソースを統合して、1つのSEOスコアにまとめます。

SEOスコアリング: 理論最大130点の内訳

Trend(0-40) + ContentGap(0-30) + GA(0-30) + FunnelBonus(0-15) + GSC(0-15) = 最大130点

各要素の計算式を見ていきましょう。

1. Trend Score(0-40点): トレンドの風に乗る

direction_multiplier = {
    "rising": 1.5,   # 上昇中 → 1.5倍ブースト
    "stable": 1.0,   # 安定 → そのまま
    "declining": 0.5, # 下降中 → 半減
}

trend_score = min(40, (avg_interest / 100) * 40 * direction_multiplier)

avg_interest 60 × rising = 60/100 × 40 × 1.5 = 36点。同じキーワードがdecliningなら60/100 × 40 × 0.5 = 12点。トレンド方向で3倍の差がつく。上り坂で記事を出すか、下り坂で出すかの違いは大きい(サーフィンで言えば、波に乗るか波に飲まれるか)。

2. Content Gap Score(0-30点): まだ誰も書いていない領域

content_gap_score = min(30, rising_count * 4 + top_count * 2)

rising_queries(上昇クエリ)が多い = まだ満足な記事がないのに検索需要が伸びている。ブルーオーシャンのシグナルです。上昇クエリ5件なら5 × 4 = 20点。

3. GA Performance Score(0-30点): 実績がある領域に上乗せ

ga_score = min(30, (views / 10) + (engagement_rate * 20))

すでにPVがある記事の関連テーマは「読者の関心が実証済み」。PV 200 × エンゲージメント率 60% = 200/10 + 0.6 × 20 = 32 → cap 30点。人気記事の続編は外しにくい、というシンプルな事実をスコアに反映しています(映画の続編は微妙になりがちなのに、ブログの続編はなぜか当たる。不思議)。

4. Funnel Gap Bonus(0-15点): ファネルの穴を埋める

コンテンツ全体で「認知→興味→検討→行動」のバランスが偏っていないかを見て、不足しているファネルの記事に加点する仕組みです。

ファネル目標比率最大ボーナス
認知(やり方、入門)40%+5点
興味(比較、おすすめ)20%+5点
検討(事例、導入、費用)30%+15点
行動(見積、依頼、相談)10%+10点

検討層の最大ボーナスが15点と高いのは意図的。技術ブログは「認知」記事に偏りがちで(「〇〇の使い方」ばかり書いてしまう)、お問い合わせにつながる検討層の記事が慢性的に不足するから。このボーナスがないと、永遠に入門記事ばかり提案されてしまいます(経験者は語る)。

計算式はこうです。

不足率 = max(0, 目標比率 - 現状比率)
ボーナス = 不足率 / 目標比率 × 最大ボーナス

検討層が現状24%(目標30%、不足6%)なら6/30 × 15 = +3点。

5. GSC Position Bonus(0-15点): 検索順位の「惜しい」を拾う

if position <= 3:
    position_score = 15.0  # トップ3は満点
elif position <= 10:
    position_score = 15.0 * (10 - position) / 7  # 4-10位は線形減衰
elif position <= 20:
    position_score = 5.0 * (20 - position) / 10  # 11-20位もワンチャン
else:
    position_score = 0.0

# インプレッション重みで実ボリュームを加味
final = position_score * min(1.0, impressions / 500)

8位でインプレッション300なら15 × (10-8)/7 × 300/500 = 2.6点。さらにGSCでクリック実績がある場合、Trend Scoreに×1.1の信頼度ブーストがかかります。Trendsの「なんとなくの人気度」がGSCの実データで裏付けられた、という意味合いです。

キーワード→ファネルの自動マッピング

# 行動(最も意図が強い)
action_patterns = ["見積", "依頼", "相談", "申込", "問い合わせ", "無料"]

# 検討
consideration_patterns = ["事例", "導入", "費用", "料金", "メリット", "デメリット"]

# 興味
interest_patterns = ["比較", "vs", "おすすめ", "ランキング", "選び方"]

# 認知(デフォルト)
awareness_patterns = ["やり方", "実装", "tutorial", "入門", "とは", "使い方"]

パターンマッチで分類しているので精度は完璧ではありません(AIが苦手な分類を正規表現が頑張っている、という逆転現象)。でも「見積」が含まれるキーワードは行動ファネル、「比較」は興味ファネルというヒューリスティックは、8割方当たる。残り2割はseo-strategy側で手動オーバーライドできるようにしてあります。

seo-strategy — クラスタ設計でコンテンツを「面」にする

seo-content-plannerが「次の1記事」を提案するのに対して、seo-strategyはサイト全体のコンテンツ戦略を設計します。

GSCクエリのクラスタリング

strategy_analyzer.pyの中核機能が、GSCの検索クエリを意味的にグルーピングするクラスタリングです。

{
  "cluster_keywords": {
    "Claude Code": ["claude code", "claude-code", "claude settings", "claude md"],
    "シフト管理": ["シフト", "shift", "勤怠"],
    "AI開発": ["ai ", "llm", "gemini", "gpt"],
    "Web開発": ["next.js", "react", "typescript", "tailwind"]
  }
}

設定ファイルでキーワード→クラスタのマッピングを定義し、GSCクエリを自動分類します。未分類の高インプレッションクエリは「その他」クラスタに集約され(「その他」という名前がすでに敗北感ありますが)、さらにそこから新クラスタ候補を自動提案するアルゴリズムが走ります。

クラスタ自動提案のアルゴリズム

1. impressions ≥ 50 の未分類クエリを抽出
2. 空白・ハイフン・アンダースコアでトークン分割
3. ストップワード除外(「の」「は」「を」「the」「is」等)
4. 共通トークンごとにクエリをグループ化(2件以上で候補)
5. total_impressions 降順ソート
6. 上位グループに含まれるクエリは下位から除外(重複除去)
7. 上位5件を出力

クラスタリングは手動で正解を教える半教師あり学習のようなもの。最初は空っぽのcluster_keywordsから始めて、自動提案を確認→良さそうなものを設定に追加、を繰り返すことでクラスタが育っていきます。

Issue自動検出

strategy_analyzer.pyは記事ごとの「問題」を閾値ベースで自動検出します。

Issue条件意味
low_ctr_high_impimp ≥ 100 かつ CTR ≤ 3%表示されてるのにクリックされない
high_bouncebounce率 ≥ 65%来たけどすぐ帰る
low_engagementエンゲージメント率 ≤ 35%読まれてるけど響いてない
position_opportunity8位 ≤ 順位 ≤ 20位もうちょっとで1ページ目
zero_clickimp ≥ 50 かつ clicks = 0表示はあるのにクリックゼロ(深刻)
zero_impressions公開30日以上 かつ imp = 0Googleに認知すらされていない

zero_clickとzero_impressionsは地味に恐ろしいシグナル。50回以上表示されてクリックがゼロならタイトルとdescriptionが検索意図と完全にずれている可能性大。公開30日でインプレッションゼロならインデックス自体に問題があるかもしれない。どちらもblog-seo-improveの出番です。

blog-seo-improve — CTRとbounce率をデータで直す

seo-strategyが「何が問題か」を特定し、blog-seo-improveが「どう直すか」を実行します。

CTR改善モード

/blog-seo-improve --type ctr

impressions ≥ 100 かつ CTR < 3% の記事を自動検出し、titleとmeta descriptionを改善提案します。

改善のロジックはシンプル。

  • キーワード前置: 重要なキーワードをタイトルの先頭に
  • 数字活用: 「5つの方法」「80%削減」など具体性を持たせる
  • クラスタキーワードとの整合: seo-strategy.jsonのクラスタ情報を参照して、同じクラスタ内の記事と一貫したキーワード戦略を維持

Bounce率改善モード

/blog-seo-improve --type bounce

bounceRate > 75% の記事に対して、冒頭セクションの結論先出しと見出し構成のスキャナビリティ向上を提案。

読者は3秒で「この記事が自分の求めている情報か」を判断する(Instagramのストーリーより短い)。冒頭に結論がないと離脱する。当たり前だけど、技術記事だと「前提知識の説明」から入りがちで、肝心の答えが中盤以降に埋もれているパターンが多い(自分の記事を振り返って「うっ」となりました)。

dry-runで安心

/blog-seo-improve --dry-run

--dry-runフラグを付ければファイルは変更せず、提案のみをレポート出力。本番の記事を壊す恐怖なしに改善案を確認できます。

blog-schedule-overview — カレンダーで「空き」を見つける

パイプラインの最終段。記事の公開スケジュールを可視化し、空きスロットを自動検出するスキルです。

/blog-schedule-overview --check --format calendar

出力イメージ:

Blog Schedule: 2026-04-07 - 2026-05-07

Week 15 (Apr 6-12)
  Mon 04/06  ✅ nextjs-mdx-blog-system
  Thu 04/09  ✅ playpark-lab-ui-components

Week 16 (Apr 13-19)
  Mon 04/13  ⬜ [empty slot]
  Thu 04/16  ⬜ [empty slot]

Week 17 (Apr 20-26)
  Mon 04/20  ✅ rust-fullstack-zero-cost-deploy
  Thu 04/23  ⬜ [empty slot]

Issues:
  - 04/13 (Mon): empty slot (seed candidates: 2)
  - 04/16 (Thu): empty slot
  - 04/23 (Thu): empty slot
  - content-strategy.json: 3 articles unscheduled

publish_daysで公開曜日を定義し(デフォルトは月・木)、MDXのfrontmatter日付を読み取ってカレンダーに配置。seed/ディレクトリの作成中記事やSNS投稿スケジュールとの照合も行います。

「空きスロットが3つ、seed候補が2つ」。次に何を書けばいいかはseo-content-plannerのスコアが教えてくれるし、空きスロットに合わせたスケジューリングもできる。計画を立てるのが苦手なエンジニアでも(私です)、データが段取りを整えてくれます。

6つのスキルの協調: 日常のワークフロー

実際の運用では、こんな流れで使っています。

月初(戦略更新):
  /seo-strategy --refresh
    → GA4/GSC/Trends を再取得
    → クラスタ分析・Issue検出
    → seo-strategy.json 更新

週次(記事企画):
  /seo-content-planner
    → SEOスコア付き記事ネタリスト
    → 上位候補からネタを選定

  /blog-schedule-overview --check
    → 空きスロット確認
    → 選定したネタをスケジュール

随時(既存記事改善):
  /blog-seo-improve --type ctr --dry-run
    → CTRが低い記事の改善案を確認
    → 納得したら --dry-run なしで適用

各スキルが独立しているので、必要なときに必要なものだけ実行できる。月初に30分、週次に10分。マーケの専門知識がなくても、データが「ここを直せ」「これを書け」と教えてくれる。

設計で意識したこと

UNIXパイプ原則: 1スキル1役割

ga-analyzerは「データ取得」だけ。trends-analyzerは「トレンド分析」だけ。seo-content-plannerは「スコアリング」だけ。1つのスキルが複数の責務を持たないようにしています。

これはテスタビリティにも直結する。ga-analyzerのテストは「正しいJSONが出力されるか」だけ見ればいい。下流のスキルを気にする必要がない。

JSONインターフェースの契約

スキル間の受け渡しはすべてJSONファイル。構造が決まっているので、途中でスキルを差し替えたり、手動でデータを書き換えたりが自由にできる。trends-analyzerがメンテ中でも、手書きのtrends_report.jsonを用意すればパイプラインは回る。

段階的なデータ充実

GA4データなし、GSCデータなし、Trendsだけ。それでも動く。すべてのデータソースがオプショナルで、あるものだけ使ってスコアリングする設計にしています。

最初はTrendsだけで始めて、GA4を設定したら精度が上がり、GSCを追加したらさらに上がる。一度に全部揃えなくても始められることが、実際に使い続けるための大事なポイントでした。

注意点・Tips

  • pytrendsのレート制限に注意: 短時間に叩きすぎるとIPブロックされます。キャッシュ(24時間)を有効にしておくのが吉。「なぜかTrendsだけ動かない」の原因は大抵これ
  • スコアは相対値: SEOスコア80点の記事ネタが「絶対に当たる」わけではない。あくまで手持ちのネタの中での優先順位。過信は禁物(スコアが高くても書き手のモチベが低いと質が落ちる。人間だもの)
  • GA4の反映ラグ: GA4 Data APIのデータは24-48時間遅れ。「今日書いた記事の効果を今日見る」は無理。焦らず1週間待ちましょう
  • クラスタは育てるもの: 最初から完璧なクラスタ定義を目指すと永遠に始まらない。3-5キーワードから始めて、自動提案を見ながら追加していくのが現実的

まとめ

「SEOはマーケの仕事」と思っていたけど、実態はデータの変換と重み付け。エンジニアが得意なやつです。

ga-analyzer → trends-analyzer → seo-content-plannerの3段パイプラインは、GA4の実績データとGoogle Trendsの需要データを掛け合わせて、「次に書くべき記事」をスコアで教えてくれる。seo-strategyがクラスタ設計でコンテンツの「面」を作り、blog-seo-improveが既存記事のCTR/bounce率を数値で改善し、blog-schedule-overviewが空きスロットを検出する。

マーケの感覚が0点でも、データが130点満点で採点してくれる。SEOの「何から手をつければ」問題、コードで解けました。

気軽に相談する


関連記事

  • Claude Code Skillsの設計思想と自作ガイド
  • ブログ公開を1コマンドで完結させる自動化設計
  • Skills連携の設計パターン — オーケストレーションとパイプライン

この技術が解決した業務課題

記事の技術が実際のプロジェクトでどう活かされているかをご紹介します

【自社導入事例】ブログ運用を完全自動化 - GitHubリポジトリから記事・サムネイル・SNS投稿まで

「ブログ書くのしんどい」「SNS投稿めんどくさい」を解決。GitHubリポジトリから記事生成、サムネイル作成、SNS投稿文まで自動化した、playpark自身の導入事例を紹介します。

事例を読む

【CrowdLog BI連携】工数レポートの遅延を85%解消した方法

CrowdLogのBI連携が遅く、工数レポートが時間通りに届かない問題を解決。処理時間を85%短縮し、リアルタイムに近い工数可視化を実現した事例をご紹介します。

事例を読む

【PDF RAG】社内文書AI検索で検索時間90%削減 - RAG導入の実践事例

PDFをアップロードするだけで自然言語で質問できるAI検索システム。RAGで文書検索時間を90%削減し、社内ナレッジの活用率を3.5倍に向上させた事例をご紹介します。

事例を読む
AI開発の導入支援

Claude CodeやAIコーディングツールの導入・カスタマイズでお困りですか?playparkでは、AI開発環境の構築から運用まで、実践に基づいた技術支援を行っています。

サービス
AI開発について相談する
ブログ一覧に戻る

関連記事

すべての記事
【Claude Code】Agent Teamで複数AIを同時に動かす - バグ調査・コード監査を並列協調で加速する設計
技術Tips
2026年3月17日20分で読める
【Claude Code】Agent Teamで複数AIを同時に動かす - バグ調査・コード監査を並列協調で加速する設計

Claude CodeのAgent Team機能を活用し、複数の専門AIエージェントが並列で協調するスキル設計を解説。バグ調査・コード監査・インシデント対応の3つの実例から、収束型マルチエージェント協調のパターンを紹介します。

Claude CodeAIAgent Team+3
【Claude Code】auto-compact対策 完全ガイド - コンテキスト消失を防ぐ状態管理の設計パターン
技術Tips
2026年2月10日22分で読める
【Claude Code】auto-compact対策 完全ガイド - コンテキスト消失を防ぐ状態管理の設計パターン

Claude Codeのauto-compactによるコンテキスト消失問題を解決する状態管理設計パターン。kickoff.jsonによる永続化・復帰ポイント設計など、Skills長時間ワークフローを確実に完遂する手法を解説。

Claude Codeauto-compact状態管理+7
【Claude Code】Skillオーケストレーション設計 - 複数Skillを連携させる実践パターン
実験レポート
2026年1月24日26分で読める
【Claude Code】Skillオーケストレーション設計 - 複数Skillを連携させる実践パターン

1つのSkillだけじゃ物足りない。GitHubリポジトリからブログ記事・サムネイル・SNS投稿まで一気通貫で自動化した「Skillオーケストレーション」の設計パターンを解説。

Claude CodeClaude Code Skillsskills+5

この技術、実際の現場ではこう使われています

記事で紹介した技術が、実際のビジネス課題をどう解決したか。導入事例で具体的なイメージをつかめます。

導入事例を見る気軽に相談する