この記事の要点(TL;DR)
- 自分の計算ツールサイトに、タイトルがまったく同じツールが2つありました。
- 片方は検索で20種類以上のキーワードに出ているのに、もう片方は28日間で3回しか表示されていませんでした。
- 原因は「共食い(カニバリゼーション)」。同じ目的のページが複数あると、検索エンジンがどちらを出すか決めきれず、両方の順位が上がりにくくなる現象です。
- 気づけたのは、Search Consoleを**「キーワード×ページ」の組み合わせ**で見たからでした。ふつうの見方では見えません。
- 直し方は「片方を消す」ではなく「役割を分ける」を選びました。その判断の理由も書きます。
個人開発で ShibaHub(shibahub.jp) という無料の計算ツールサイトを運営しています。ツールが150個くらい、解説記事が150本くらいあります。
数が増えてくると、自分でも何を作ったか把握しきれなくなります。今回はそれが原因で起きた失敗です。
そもそも「共食い」とは
まず用語の説明から。
共食い(キーワードカニバリゼーション) とは、同じ検索キーワードを狙ったページが自分のサイト内に複数あって、お互いの順位を下げ合ってしまう状態のことです。
検索エンジンは「この検索には、このサイトのどのページを出すのが正解か」を決めます。似たページが2枚あると、
- 評価(他サイトからのリンクや、ユーザーの反応)が2枚に分散する
- どちらを出すか毎回ブレる
ということが起きます。1枚に集約していれば上位に行けたかもしれないのに、2枚に割れて両方とも中途半端になる、というイメージです。
何が起きていたか
私のサイトには、こういう2つのツールがありました。
| URL | ページのタイトル |
|---|---|
/tools/hand-salary-calculator |
手取り計算ツール 年収・月給から社会保険料・税金を差し引いた額がわかる |
/tools/net-income-calculator |
手取り計算ツール(簡易) 年収から月々の手取りを概算 |
タイトルの頭がどちらも「手取り計算ツール」です。
作ったときの記憶をたどると、たぶん先に簡易版を作って、あとから高機能版を作って、簡易版を消すのを忘れたのだと思います。悪意はないのですが、結果としてほぼ同じものが2つ並んでいました。
数字で見るとはっきりしていた
Search Console(Googleが提供している、自分のサイトが何の検索で何位に出ているかを見られる無料ツール)で調べたところ、こうなっていました。
| 出ているキーワードの数 | 表示回数(28日) | |
|---|---|---|
hand-salary-calculator(高機能版) |
20種類以上 | 多数 |
net-income-calculator(簡易版) |
3種類 | 3回 |
簡易版が受けていたのは、この3つだけでした。
1表示 91位 手取り シミュレーション
1表示 94位 手取り 計算
1表示 96位 手取り 計算 表
91位・94位・96位です。検索結果は1ページに10件なので、10ページ目くらいということになります。実質、誰の目にも触れていません。
しかも簡易版は、機能でも高機能版に完全に負けていました。高機能版には都道府県別の保険料率も、扶養の人数も、ボーナスの計算もあります。簡易版には年収と年齢と「扶養あり/なし」しかありません。
下位互換のページが、上位互換のページと同じ名前で置いてある。 これが実態でした。
なぜ今まで気づかなかったのか
Search Consoleは、ふつうに開くと次のような見方ができます。
- キーワード別:どんな検索で出ているか
- ページ別:どのページが何回表示されたか
でも、これを別々に見ていると**「どのページが、どの検索で出ているか」が分かりません**。
- キーワード別で見ると「手取り 計算 → 94位」としか出てこない
- ページ別で見ると「
/tools/net-income-calculator→ 3表示」としか出てこない
この2つが同じ問題の別の顔だと気づけないんです。
そこでAPIを使って、キーワードとページを組み合わせた形で取り直しました。Search Console APIには dimensions という指定があり、ここに2つ並べると組み合わせで取れます。
res = sc.searchanalytics().query(
siteUrl="sc-domain:example.com",
body={
"startDate": "2026-07-03",
"endDate": "2026-07-31",
"dimensions": ["query", "page"], # ← ここがポイント。1つだけだと見えない
"rowLimit": 5000,
"dataState": "all",
},
).execute()
この形で出すと、こうなります。
11表示 0click 97.6位 フリーランス 手取り 計算 -> /category/finance
1表示 0click 94.0位 手取り 計算 -> /tools/net-income-calculator
1表示 0click 91.0位 手取り シミュレーション -> /tools/net-income-calculator
一気に見えるようになりました。ついでに「フリーランス 手取り 計算」という検索を、ツールではなくカテゴリ一覧ページが受けていることも分かりました(これは「ちょうどいいページが無いので、仕方なく一覧が出ている」というサインです)。
ちなみに
dataState: "all"を付けると、まだ確定していない直近のデータも含めて取れます。付けないと数日ぶんが欠けます。
どう直したか:消すか、分けるか
やり方は2つ考えられました。
案A:簡易版を消して、高機能版にリダイレクト(転送)する
- 素直。共食いは確実に消える
- ただしページが1枚減るだけで、新しく取れる検索は増えない
案B:役割を分ける
- 高機能版を「会社員の手取り計算」に
- 簡易版を「フリーランス・個人事業主の手取り計算」に作り替える
私は案Bにしました。理由は、さっき見つけた「フリーランス 手取り 計算」がカテゴリ一覧で受けられていた、という事実があったからです。
フリーランスの手取りは、会社員とは計算がまったく違います。
- 会社員:収入から「給与所得控除」という決まった額を引く
- フリーランス:実際にかかった経費を引く。さらに青色申告特別控除がある
- 会社員:健康保険と年金の半分を会社が払ってくれる
- フリーランス:国民健康保険と国民年金を全額自分で払う
つまり、そもそも別のツールであるべきものが、間違って同じ名前で並んでいたわけです。だったら分けるほうが、共食いも消えるし、空いていた検索も拾える。一石二鳥だと考えました。
やったことはこれだけです。
- 簡易版の計算ロジックをフリーランス向けに書き直す
- 両方のタイトルに「(会社員)」「フリーランス・個人事業主の」を明記する
- お互いへのリンクを張る(「あなたが会社員ならこちら」と案内する)
- それぞれに解説を足す
学んだこと
① ページが増えたら、定期的に「同じことをしているページ」を探す
150ページを超えたあたりから、私はもう全部を覚えていませんでした。タイトルの重複チェックくらいは自動でやったほうがいいと反省しています。実際、今回のケースはツールの定義ファイルからタイトルを取って先頭を比べるだけで見つかったはずです。
② 「キーワード×ページ」で見ないと見えない問題がある
順位が上がらない理由を「記事が足りない」「内容が薄い」と考えがちですが、自分のページ同士が競合しているだけということがあります。これはキーワード単体・ページ単体では絶対に見えません。
③ 重複を見つけても、いきなり消さなくていい
「片方消す」は思考停止になりがちです。2つあるということは、2つ作りたくなる理由があったのかもしれません。今回は「会社員とフリーランスで計算が違う」という、分けるべき正当な理由が実際にありました。
おまけ:作業中に別のバグも見つかりました
フリーランス版の計算を書くにあたって税制を調べ直したところ、もとからあった高機能版のほうの数字が古いことに気づきました。基礎控除という、誰にでも適用される控除の額が、法改正前の値のままだったんです。
こちらは正確な資料が手元に揃わなかったので、今回は直さず「ここが古い」というメモだけ残しました。中途半端な知識で税額計算を書き換えると、もっとひどいことになるからです。
「気づいたけど今日は直さない」も選択肢だと思っています。直さないことより、気づいたのに記録を残さないことのほうが危ないので、コードのコメントとドキュメントの両方に理由つきで書いておきました。
同じように「ツールをたくさん作ったけど順位が上がらない」という方は、一度キーワード×ページで見てみると、思わぬ共食いが見つかるかもしれません。