Communityコーディング&開発github.com

ブログカニバリゼーション - キーワード重複検出

複数のブログ投稿が同じ検索キーワードで競合していないかを検出します。ローカルモード(デフォルト)とDataForSEO APIモードの2つのモードを提供します。

ブログカニバリゼーション - キーワード重複検出 とは?

このスキルは、同一ドメイン内の複数のブログ投稿が同じ検索キーワードに対してランキング競合(カニバリゼーション)を起こしていないかを分析するツールです。開発者やコンテンツマーケターは、このツールを使ってSEOパフォーマンスを低下させる要因を特定し、改善できます。 2つの動作モードがあります。**ローカルモード**(デフォルト)は無料で、ファイル内容の分析(Grep/Read)によりキーワードの重複を検出します。**APIモード**(`--api`フラグ)はDataForSEOのエンドポイント(Page IntersectionおよびRanked Keywords)を呼び出し、SERP(検索結果ページ)レベルのデータ(検索ボリューム、掲載順位、CPCなど)を取得します。APIモードでは環境変数`DATAFORSEO_LOGIN`と`DATAFORSEO_PASSWORD`の設定が必要で、1回のAPI呼び出しあたり約$0.01のコストがかかります。 分析は5つのステップで進行します。1) ブログファイルのスキャン、2) 各ファイルからのプライマリキーワード抽出、3) 類似性(完全一致、語幹一致、意味的重複、サブセット一致)によるクラスタリング、4) 各クラスタの深刻度スコアリング、5) レポート出力。ローカルモードでは簡易ヒューリスティック(例:プライマリキーワードの完全一致はCritical)を使用しますが、APIモードでは`overlap_count x avg_search_volume x (1 / position_gap)`という数式でより正確なスコアを計算します。 出力はサマリテーブル(競合している投稿ペア、共有キーワード、深刻度、推奨アクション)と、クラスタごとの詳細レポート(重複キーワード一覧、どちらの投稿が強いか、具体的な推奨事項とその根拠)を含みます。推奨アクションは「MERGE」(結合)、「DIFFERENTIATE」(差別化)、「CANONICAL」(正規化)、「NO ACTION」(様子見)の4種類で、それぞれに具体的な実装手順が示されています。エラーハンドリングも充実しており、ブログファイルが見つからない場合、API認証情報不足時(自動的にローカルモードにフォールバック)、レート制限(リトライ)などに適切に対応します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/AgriciDaniel/claude-blog/tree/main/skills/blog-cannibalization

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

ブログカニバリゼーション - キーワード重複検出 は何をしますか?

複数のブログ投稿が同じ検索キーワードで競合していないかを検出します。2つのモードがあります。 ローカル専用分析(デフォルト)とDataForSEO APIモード(SERPレベルのデータ用)です。

2つのモード

モードフラグコストデータソース
ローカル(デフォルト)無料Grep/Readによるファイル内容分析
API--api~$0.01/コールDataForSEO Page Intersection + Ranked Keywords

ローカルモードはAPIキー不要で動作します。APIモードではDataForSEOの認証情報を環境変数として設定する必要があります:DATAFORSEO_LOGIN と DATAFORSEO_PASSWORD。

ローカルモードのワークフロー

ステップ 1: ブログファイルのスキャン

Globを使用して、対象ディレクトリ内のすべてのコンテンツファイルを検索します。

  • パターン: **/*.md, **/*.mdx, **/*.html
  • node_modules/, .git/, drafts/ ディレクトリはスキップ

ステップ 2: プライマリキーワードの抽出

各ファイルについて、以下のソースからキーワードシグナルを読み取り抽出します。

  • タイトルタグ または H1見出し(最も高い重み)
  • H2見出し(中程度の重み)
  • 最初の段落(補助的なシグナル)
  • メタデスクリプション(フロントマターに存在する場合)

プライマリキーワード抽出方法:

  1. タイトルとH1を1-gram、2-gram、3-gramフレーズにトークン化
  2. タイトル + H2 + 最初の段落における出現頻度で各フレーズをスコアリング
  3. 最もスコアの高い2〜3語のフレーズをプライマリキーワードとして選択
  4. H2見出しからセカンダリキーワードを記録

ステップ 3: 類似性によるクラスタリング

以下のマッチングルール(優先順位順)を使用して投稿をグループ化します。

  1. 完全一致 - 2つ以上の投稿で同一のプライマリキーワード
  2. 語幹一致 - 同じ語幹を持つ(例:「最適化」と「最適化する」)
  3. 意味的重複 - Claudeが2つのキーワードが同じ検索意図をターゲットにしていると判断(例:「顧客管理CRM おすすめ」と「トップCRMツール 2026」)
  4. サブセット一致 - 一方のキーワードがもう一方を含む(例:「メールマーケティング」と「メールマーケティング スタートアップ向け」)

ステップ 4: スコアリングとフラグ

2つ以上の投稿を含む各クラスタについて、深刻度を評価し推奨事項を生成します。

ステップ 5: レポート出力

結果テーブルとクラスタごとの推奨事項を表示します。

APIモードのワークフロー(DataForSEO)

--apiフラグが必要です。WebFetchを使用してDataForSEOエンドポイントを呼び出します。

使用するエンドポイント

Page Intersection - 複数のURLがランキングしているキーワードを検出:

POST https://api.dataforseo.com/v3/dataforseo_labs/google/page_intersection/live
Authorization: Basic <base64(login:password)>

{
  "pages": {
    "1": "https://example.com/post-a",
    "2": "https://example.com/post-b"
  },
  "language_code": "en",
  "location_code": 2840
}

コスト: 約$0.01/コール。重複キーワードとその掲載順位、検索ボリューム、CPCを返します。

Ranked Keywords - 単一URLがランキングしているすべてのキーワードを取得:

POST https://api.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live

{
  "target": "https://example.com/post-a",
  "language_code": "en",
  "location_code": 2840
}

分析手順(APIモード)

  1. ユーザー(またはサイトマップ)から公開URLをすべて収集
  2. 各URLに対してRanked Keywordsを実行し、キーワードプロファイルを構築
  3. キーワードクラスタを共有するURLペアに対してPage Intersectionを実行
  4. 以下の計算式で深刻度を計算
  5. 検索ボリュームと掲載順位データを含む拡張レポートを出力

深刻度スコアリング

重複シグナルに基づく4つの深刻度レベル:

レベル基準アクションの緊急度
Critical同一の完全一致キーワード、両方のページがトップ20即時
High同一キーワードクラスタ、一方のページがもう一方を上回っている今週中
Medium関連キーワードで部分的なSERP重複今月中
Low意味的類似性があるが、確認された意図は異なる監視

深刻度計算式(APIモード)

severity_score = overlap_count x avg_search_volume x (1 / position_gap)

ここで:

  • overlap_count = 共有ランキングキーワード数
  • avg_search_volume = 共有キーワードの月間平均検索ボリューム
  • position_gap = 平均掲載順位の絶対差(最小1)

スコアが高いほど、カニバリゼーション問題が緊急であることを示します。

深刻度ヒューリスティック(ローカルモード)

SERPデータがない場合、簡易スコアリングを使用:

  • Critical: 投稿間でのプライマリキーワードの完全一致
  • High: プライマリキーワードの語幹一致、または3つ以上の共有H2キーワード
  • Medium: プライマリキーワードの意味的重複
  • Low: サブセット一致のみ、または共有セカンダリキーワード

出力形式

サマリテーブル

| 投稿A | 投稿B | 共有キーワード | 深刻度 | 推奨事項 |
|--------|--------|----------------|--------|----------|
| /best-crm-tools | /top-crm-software | best crm, crm tools, crm software | Critical | MERGE |
| /email-tips | /email-marketing-guide | email marketing | High | DIFFERENTIATE |
| /seo-basics | /seo-for-beginners | seo basics, beginner seo | Critical | CANONICAL |
| /react-hooks | /react-state-mgmt | react, state | Low | NO ACTION |

クラスタごとの詳細

フラグされた各クラスタについて、以下を提供:

  • 両方の投稿タイトルとURL
  • 重複キーワードの完全なリスト(APIモードの場合は検索ボリューム付き)
  • どちらの投稿が強いか(より包括的、構造が良い)
  • 根拠付きの具体的な推奨事項

推奨事項

カニバリゼーションクラスタごとに4つの可能なアクション:

MERGE

両方のページが薄い、または同じ意図を同程度の深さでカバーしている場合。

  • 両方のコンテンツを組み合わせて、1つの包括的な投稿を作成
  • 弱い方のURLをマージ後の投稿に301リダイレクト
  • どちらかのURLを指すすべての内部リンクを保持

DIFFERENTIATE

ページが異なる意図を持っているが、キーワードターゲティングが重複している場合。

  • 弱い方の投稿のプライマリキーワードを、関連するロングテールキーワードに変更
  • タイトル、H1、メタデスクリプションを新しい焦点に合わせて更新
  • 2つの投稿間に内部リンクを追加し、異なるトピックであることを強調

CANONICAL

一方の投稿が明らかに権威があり、もう一方が価値の低い重複である場合。

  • 弱い方のページに権威ページを指す rel="canonical" を追加
  • 弱い方のページが独自の価値を追加しない場合は、noindexを検討
  • 弱い方のページから権威ページへのリンクを設置

NO ACTION

表面的なキーワード類似性にもかかわらず、意図が真に異なる場合。

  • 将来の監査のためにその理由を文書化
  • 四半期ごとにランキングの変動を監視
  • どちらかの投稿のランキングが低下した場合に再評価

エラーハンドリング

  • ブログファイルが見つからない場合: ディレクトリに.md、.mdx、.htmlファイルが含まれていない場合、「[ディレクトリ]にブログファイルが見つかりません」と報告し、パスを確認するよう提案
  • DataForSEO認証情報不足: APIモードで認証情報が設定されていない場合、自動的にローカルモードにフォールバックし、ユーザーに通知
  • APIレート制限: DataForSEOには1分あたりのレート制限があります。429レスポンスを受信した場合、待機して1回再試行。それでも続く場合は、残りのURLをローカルモードで処理
  • WebFetch失敗: ソースURLにアクセスできない場合、そのURLをスキップし、レポートに「確認不能 - ソースが利用できません」と記載
  • 投稿が1つだけのディレクトリ: ブログ投稿が1つだけの場合、「カニバリゼーション分析には少なくとも2つの投稿が必要です」と報告し、正常に終了

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

関連スキル