SEOキーワード密度を計算して過剰最適化を検出
キーワード密度レポートは、繰り返しが多いという曖昧な印象を、再現可能な数値へ変換します。ページ本文を貼り付け、対象の単語またはフレーズと警告を出す割合を指定してください。正確な出現回数、キーワードが本文に占める割合、過剰最適化の判定を返します。ローカルかつ決定論的に処理するため、ページを取得したり表示内容を推測したりせず、編集確認、公開フロー、繰り返し可能な品質基準に利用できます。
無料で実行
対象フレーズを一貫した方法で測定します
キーワードの確認は、担当者によって数え方が変わりがちです。完全なフレーズだけを数える方もいれば、単語の一部を含める方や、原稿を見て頻度を推測する方もいます。このレポートは一定の規則を適用します。大文字と小文字、互換性のあるUnicode表記を正規化し、本文とキーワードを単語に分けてから、完全な並びを検索します。「靴」は別の語形を自動的には数えず、複数語のフレーズは同じ順序で隣接する場合だけ一致します。単語間の句読点は一致を妨げません。重なる出現も数えるため、反復表現を数学的に漏れなく扱えます。total_wordsも返すので、割合だけでなく分母も確認できます。可能であれば公開時の表示本文を入力してください。入力されていないナビゲーション、非表示マークアップ、その他の内容は結果に影響しません。URLを取得せず指定された本文だけを分析するため、同じ入力からは常に同じ結果が得られ、校閲時にも再現できます。
密度と警告しきい値を正しく解釈します
密度は、一致したキーワードが占める単語数を本文の総単語数で割り、100を掛けて求めます。3語のフレーズが2回見つかった場合、分子には6語が加わります。この定義により、長いフレーズを過小評価せず、単語と比較できます。結果は小数第2位までに丸めます。thresholdには運用で許容する最大割合を設定し、既定値は3です。over_optimizedは密度がしきい値を超えた場合だけ真になり、同じ値では真になりません。そのため、自動判定の境界が明確です。警告は人による確認を促すもので、検索順位の低下を証明するものではありません。検索エンジンは普遍的な理想密度を公表しておらず、自然な反復は題材、形式、ブランド名、専門用語によって異なります。しきい値は社内の一貫性基準として使い、似た種類のページを比較し、修正前に該当箇所をお読みください。機械的に反復をすべて削ると、正確な文章が分かりにくくなる場合があります。
編集ワークフローにレポートを組み込みます
見出し、行動喚起、キャプション、本文が公開版に近づいた段階で実行してください。制作チームは、回数、割合、しきい値、判定を各原稿と一緒に保存し、修正後に同じリクエストを再実行して変更を確認できます。商品ページ、用語集、長文記事に異なるしきい値を適用しても、計算方法は変わりません。公開前チェックに組み込み、本文と対象キーワードを送信してover_optimizedを確認し、警告された原稿を理由とともに編集者へ戻すこともできます。生の項目が残るため、判断を監査できます。空の本文は有効で、単語数、出現回数、密度はいずれも0になります。一方、空のキーワードは測定対象がないため拒否されます。ネットワーク、乱数、時刻、モデルを使わないので、バッチ結果も決定論的です。APIリクエストごとの料金は$0.002で、ブラウザーでも同じ純粋な計算を利用できます。
活用例
公開前の原稿を確認します
最終本文の対象フレーズを測定し、予想外に反復した原稿を編集担当者の確認へ戻せます。
コンテンツ品質ルールを適用します
公開フロー全体で明確なしきい値を使い、各警告の根拠となる回数と割合を保存できます。
改稿結果を同じ基準で比較します
修正前後に同じ設定を使い、測定方法を変えずに過剰な反復が減ったか確認できます。
よくある質問
キーワード密度はどのように計算しますか?
完全一致が占める単語数を総単語数で割って100を掛け、小数第2位までに丸めます。
大文字と小文字の違いは無視しますか?
はい。本文とキーワードの表記を正規化しますが、完全な単語境界とフレーズの順序は区別します。
どの時点で過剰最適化と判定されますか?
計算した密度が指定したしきい値を厳密に超えた場合に真となります。既定値は3パーセントです。
警告は検索順位の低下を証明しますか?
いいえ。指定されたルールに基づく編集上の注意であり、検索エンジンによるペナルティの予測ではありません。
APIリクエストの料金はいくらですか?
1回につき$0.002です。決定論的な計算なので、ページ取得や外部モデルは必要ありません。
開発者向け — APIアクセス
このページの機能はすべてAPIからも利用できます。自社システムに組み込みたいチーム向けのセクションです。それ以外の方は上のツールをそのままお使いください。
エンドポイント
Bearerトークンで認証し、POST1回でタスクをキューに登録します。結果はWebhookまたは署名付きリンクで受け取れます。
お使いのスタックから呼び出す
curl -X POST https://api.kit.forhosting.com/seo/keyword-density-report \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Technical SEO helps a site become easier to crawl. A practical technical SEO review checks structure without forcing technical SEO into every sentence.","keyword":"technical SEO"}'const res = await fetch("https://api.kit.forhosting.com/seo/keyword-density-report", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Technical SEO helps a site become easier to crawl. A practical technical SEO review checks structure without forcing technical SEO into every sentence.",
"keyword": "technical SEO"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/seo/keyword-density-report",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Technical SEO helps a site become easier to crawl. A practical technical SEO review checks structure without forcing technical SEO into every sentence.",
"keyword": "technical SEO"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/seo/keyword-density-report", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Technical SEO helps a site become easier to crawl. A practical technical SEO review checks structure without forcing technical SEO into every sentence.","keyword":"technical SEO"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Technical SEO helps a site become easier to crawl. A practical technical SEO review checks structure without forcing technical SEO into every sentence.","keyword":"technical SEO"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/seo/keyword-density-report", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)リクエスト例
{
"text": "Technical SEO helps a site become easier to crawl. A practical technical SEO review checks structure without forcing technical SEO into every sentence.",
"keyword": "technical SEO"
}レスポンス例
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "seo.keyword_density_report",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}非同期APIです。task_idは即時に返ります。ポーリングは1秒あたり1リクエストまでです。
料金
単価はすべて公開しています。トークン換算や独自クレジットはありません。失敗したタスクは課金されません。
エラー
| HTTP | コード | 意味 |
|---|---|---|
401 | unauthorized | APIキーが無効か、指定されていません。Authorizationヘッダーを確認してください。 |
402 | insufficient_balance | 残高が不足しています。チャージ後に再度お試しください。 |
404 | unknown_type | 指定されたタスクタイプは存在しません。タイプ名を確認してください。 |
429 | rate_limited | リクエストが多すぎます。しばらく待ってから再度お試しください。 |