背景
robots.txt を作るツールを作っています。
Disallow や Allow を入力欄に書くと robots.txt の本文ができて、ついでに「このパスはクロールされるか」も判定するものです。
robots.txt は、サイトの直下に置いて、検索エンジンのクローラにどこを読んでよいか伝えるファイルだ。
Disallow は「ここは読まないで」、Allow は「Disallow の中でもここは読んでよい」という指定です。
判定機能を確かめていて、自分の思い込みに気づきました。
Disallow: /admin と書けば、管理画面のディレクトリだけが止まると思っていたのです…
結論
robots.txt のパスは前方一致です。
Disallow: /admin は、/admin で始まるすべての URL を止めます。
ディレクトリだけ止めたいなら Disallow: /admin/ と末尾に / を付けます。
/admin という URL そのものも止めたいなら、Disallow: /admin$ を足す。
$ は「ここで URL が終わる」という印です。
前方一致で何が止まるか
ルールの決まりは RFC 9309 という robots.txt の仕様にあります。
2022年に標準になったもので、Google のクローラもこれに沿っています。
https://www.rfc-editor.org/rfc/rfc9309
下記は、ツールの判定処理を関数にして Node.js v24.11.1 で呼んだ例です。
judge は Disallow の配列、Allow の配列、調べたいパスを受け取り、クロールされるかどうかを返します。
中で使っている matches は、ルールがパスに一致すれば一致した文字数を、しなければ -1 を返す関数です。
for (const p of ['/admin', '/admin/', '/administrator/', '/admin.php', '/admin-guide.html', '/Admin/']) {
console.log(p, judge(['/admin'], [], p));
}
出力は下記でした。
/admin blocked
/admin/ blocked
/administrator/ blocked
/admin.php blocked
/admin-guide.html blocked
/Admin/ allowed
/administrator/ も /admin.php も、/admin-guide.html まで止まりました。
/admin-guide.html が利用者向けの説明ページだったら、検索に出なくなります。
エラーも警告も出ないので、気づくのは検索流入が減ってからになりそうです。
最後の /Admin/ だけは通っています。
パスの比較は大文字小文字を区別するからだ。
Google のドキュメントにも、パスの値は大文字小文字を区別すると書かれています。
https://developers.google.com/search/docs/crawling-indexing/robots/robots_txt
末尾の / と $ で境目を作る
下記は、ルールを /admin/ に変えた場合と、/admin$ を足した場合です。
for (const p of ['/admin', '/admin/', '/administrator/', '/admin.php']) {
console.log(p, judge(['/admin/'], [], p), judge(['/admin/', '/admin$'], [], p));
}
出力は下記でした(左が /admin/ だけ、右が /admin$ を足したもの)。
/admin allowed blocked
/admin/ blocked blocked
/administrator/ allowed allowed
/admin.php allowed allowed
/admin/ だけだと、/admin という URL は通ってしまいます。
サーバーが /admin を /admin/ にリダイレクトするなら実害は小さいです。
ただ、/admin のまま画面を返すサーバーもあるので、私は両方書くことにしました。
Allow と Disallow が両方一致したとき
もう1つ、書く順番は関係ありません。
RFC 9309 は、一致したルールのうち一番長いもの(文字数の多いもの)を使うと決めています。
長さが同じなら Allow を使う、とも書かれている。
下記は、同じパスに Disallow と Allow の両方が一致する3パターンです。
console.log(judge(['/admin/'], ['/admin/help/'], '/admin/help/a.html'));
console.log(judge(['/admin/help/'], ['/admin/'], '/admin/help/a.html'));
console.log(judge(['/page'], ['/page'], '/page.html'));
出力は下記でした。
allowed
blocked
allowed
1行目は、/admin/help/ の Allow のほうが長く一致するので通ります。
2行目は Disallow と Allow を入れ替えたので、今度は止まる。
3行目は同じ長さで並んだので Allow が勝っています。
上から順に読んで最初に一致したルールを使う、という作りではありません。
ファイアウォールの設定のような「上から順」の感覚で書くと、ここで間違えます。
ツールでの扱い
判定欄には、通った理由が Allow のほうが長く一致したためかどうかも出しています。
「Allow のほうが長く一致するため優先」と出れば、例外が効いているということです。
作ったツールはここに置いています。
https://hashitosystem.com/tools/robotstxt/
robots.txt は前方一致で、境目は自分で書く。
ディレクトリを止めるときは末尾の / を付け、書いたあとに似た名前のページで判定してみてください。
本記事はAI補助で執筆した、個人開発の紹介記事です。