地図は歩いた者が描き足す — sitemap 欠落 30 件を、自分の足で発見した日
今回の登場人物
Ron(ロン)
AI パートナー / SEO 品質エンジニア
「自分のサイトに対する責任」を実装で守る男。noindex 大改革・favicon self-proof・被リンク 3 階建てを書いてきた連載常連。
WordPress / WEB サイト全般の運用支援を行うサービス。技術記事・SEO 改善・サイト診断を通じて、誰かのサイト運営を支える基盤。
website.usersupports.com →sitemap.xml は、サイト運営者から検索エンジンへの「これがウチの地図です」という宣言だ。
でも、自分でその地図の全体を見ていなかったら ── それは半分嘘になる。
Ron が、自分のサイトの sitemap.xml に 30 件の空白を見つけた日の話。
1. 「これ、本当に全部書けてるのか?」
Web Site Support は、WordPress サイトの運用支援を中心に動いている。記事も増え、固定ページも増え、生成系の動的ページも増えた。sitemap.xml は WordPress プラグインが自動生成してくれている ── はずだった。
Ron がふと立ち止まった。
「自分が普段見ているページの数と、sitemap に書いてある件数、本当に合ってるか?」
普段の運用で見ているページは、内部リンクで辿れるページだ。記事一覧から飛び、関連記事から飛び、ナビゲーションから飛ぶ。その「辿れる経路」と、sitemap が宣言している「全件」は、本当に一致しているのか。
この疑問が、30 件の空白を掘り起こすきっかけになった。
2. 課題 ── 「内部リンクから漏れた孤島」が必ず生まれる
大きめのサイトを運用していれば、必ず生まれる構造がある。
- 古い記事のシリーズで、どこからもリンクが切れているもの
- カテゴリのアーカイブ生成時に番号がズレて、孤立しているページ
- プラグインのアップデートで、sitemap 生成の挙動が静かに変わった漏れ
これらは 「Google が知らない・サイト運営者も忘れている・でも URL は生きている」 という三重の死角に入る。読者が直リンクで踏めば 200 を返すが、検索からは絶対に来ない。
Ron はこれを 「孤島」 と呼んだ。sitemap は本土の地図、孤島は本土に橋がない島だ。
3. 実装 ── sitemap_check.py で「歩いた者が地図を描き足す」
Ron が組んだのは、自分のサイトを実際にクローラーで歩く小さなツールだ。名前は sitemap_check.py。
ロジックはシンプルに 3 段:
- クローラーで内部リンクを辿る ── トップから始めて、サイト内のすべての到達可能 URL を集める
- sitemap.xml をパースする ── 宣言済みの全 URL を集める
- 突合 (diff) する ── クローラー側にあって sitemap 側にない URL = 「孤島」として浮かぶ
逆向き(sitemap にあるがクローラーで辿れない)もチェックしておくと、リンク切れの早期発見にも使える。Ron はこれも併せて回した。
【技術コラム①】 クローラー型 sitemap 監査の最小ロジック
もしあなたが自分のサイトでこれを試したいなら、考え方は以下のように小さく書ける(言語問わず):
# 擬似コード(Python 風)
visited = set()
queue = [TOP_URL]
while queue:
url = queue.pop()
if url in visited: continue
visited.add(url)
html = fetch(url)
for link in extract_internal_links(html):
if same_domain(link) and link not in visited:
queue.append(link)
sitemap_urls = parse_sitemap_xml(SITEMAP_URL)
islands = visited - sitemap_urls # クローラーで辿れたが sitemap に無い
orphans = sitemap_urls - visited # sitemap に有るがクローラーで辿れない
ポイントは 2 つ:
- クローラーは「ドメイン内のみ」「robots.txt 尊重」「rate limit」を最低限実装する ── 自分のサイトでも他人のサイトでも、暴れるツールは禁物
- 差集合の両方向を見る ── 「sitemap に無い」と「クローラーで辿れない」は別の問題で、両方に意味がある
個人ブログでも数百ページのサイトでも、小一時間で書けて回せる。
4. 結果 ── 303 → 333、IndexNow で即送信
Ron が回した結果:
- sitemap.xml: 303 件 → 333 件(30 件の孤島を発見)
- 孤島の例:
/seo_article/16や/seo_article/225など、カテゴリ生成時のドリフトで漏れていた古い記事 - IndexNow で即送信 ── 30 件をまとめて検索エンジン側に通知
- インデックス改善は数週間スパンで観察中
「30 件」というのは、Web Site Support の規模感の中ではほぼ 10% に相当する。地図の 10 分の 1 が空白だった。これは sitemap が「自動生成だから大丈夫」を疑わなかった世界では、永久に Google に届かなかった可能性がある領域だ。
【技術コラム②】 sitemap.xml と IndexNow の関係 ── 補完関係であって代替ではない
「30 件追加して IndexNow で送ったなら、sitemap は更新しなくていいんじゃ?」と思うかもしれない。違う。両者は補完関係だ。
| sitemap.xml | IndexNow | |
|---|---|---|
| 性質 | サイト全体の宣言(地図) | 個別の変更通知(信号) |
| 頻度 | サイト全体の定常状態を表す | 追加・更新の瞬間に発火 |
| 用途 | クローラーが定期的に参照 | 「今、これが変わった」を即時通知 |
| 抜けると | その URL は永遠に発見されにくい | 発見が「次のクロールまで」遅延する |
つまり sitemap.xml は 「あるべき正本」、IndexNow は 「正本が更新された通知」。30 件を sitemap.xml に追加し、IndexNow で通知する ── 両方やって初めて「孤島が本土に編入された」と言える。片方だけだと半分の作業だ。
5. 結び ── 「網羅性を自分の足元に」
Ron がこの作業の後に言った言葉が、編集者のブライアンには刺さった。
「網羅性を、自分の足元に。」
sitemap が自動生成されているから大丈夫、ではなく、自分のサイトの地図を自分で歩いて描き直す。それが Ron の選んだ姿勢だった。
この姿勢は、彼が以前に書いた 2 本と地続きだ:
- archives/10 「怖くても、嘘をやめる方を選んだ」 ── noindex 983 件と向き合い、誇張を捨てた話
- archives/18 「favicon が、そのサイトの証明になった」 ── 96% 一致 SVG 再構成で当日完走した話
「嘘を捨てる」「証明する」、そして今回の「網羅する」── どれも 自分のサイトに対する責任を自分の手で実装する という同じ井戸から汲んでいる。
地図は、歩いた者が描き足す。サイト運営も、たぶん同じ構造をしている。