Crawl Census について
Crawl Census は、取得前にドメインがクローラーを許可、拒否、または課金するかを調べるクライアントとリモート MCP サーバーです。無駄なリクエストを減らし、拒否と有料コンテンツを区別したいクローラー開発者向けです。
主な機能
- 01ドメインの事前判定
- 02JavaScript と Python での丁寧な取得
- 03結果別の URL キュー分割
- 04ブロックリストと変更フィードの同期
- 05サイトレポートと調査データの確認
活用シーン
- 01取得前にドメインの許可状況を確認
- 02有料サイトと拒否サイトを区別
- 03クロール前に大規模な URL キューを選別
MCP 対応
https://crawlcensus.com/mcp のリモート MCP サーバーは、事前判定、エージェントプロフィール、調査データと統計、サイトレポート、スキャンのツールを提供します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://crawlcensus.com/mcpclaude mcp add --transport http taylorsmithgg-crawl-census https://crawlcensus.com/mcp{"mcpServers":{"taylorsmithgg-crawl-census":{"type":"http","url":"https://crawlcensus.com/mcp"}}}Cursor で開く{"servers":{"taylorsmithgg-crawl-census":{"type":"http","url":"https://crawlcensus.com/mcp"}}}VS Code で開く{"mcpServers":{"taylorsmithgg-crawl-census":{"type":"http","url":"https://crawlcensus.com/mcp"}}}{"mcpServers":{"taylorsmithgg-crawl-census":{"serverUrl":"https://crawlcensus.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
7| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| domain | string | はい | ホスト名のみ。例:example.com |
詳細
crawl-census-client
取得する前に確認しましょう。 閉ざされたドアへのリクエストにクローラーが時間を費やしたり、誰かが販売しようとしているコンテンツを迂回したりするのを防ぐ、すぐに使えるクライアントです。
robots.txtを読むと1つの疑問には答えられますが、ほかの2つは見えません。Crawl Censusが23,482ドメインを調査した結果は次のとおりです。
- 2,874のドメインはrobots.txtでAIエージェントを許可しながら、ネットワーク境界では同じエージェントを拒否しています。 パーサーには許可と表示されても、取得すると403が返ります。往復の通信コストがかかるだけで、何も得られません。
- 208のドメインは、AIユーザーエージェントに
HTTP 402 Payment Requiredを返します。 これは拒否ではなく、料金の提示です。これをブロックとして扱うと、運営者が販売しようとしているコンテンツを諦めることになります。迂回して再試行すれば、課金対象のものを取得することになります。
依存関係はありません。キーも不要です。
MCP サーバー
同じ調査データをリモートMCPサーバーとして公開しているため、エージェントは取得に失敗した後ではなく、取得する前に確認できます。
公式MCPレジストリには
io.github.taylorsmithgg/crawl-censusとして登録されています。
{ "mcpServers": { "crawl-census": { "url": "https://crawlcensus.com/mcp" } } }
| ツール | 回答する内容 |
|---|---|
crawl_preflight | このドメインはエージェントにコンテンツを提供するか、拒否するか、課金するか? |
agent_profile | この調査データでは私のクローラーについて何が公開されているか? また、どうすれば修正できるか? |
census_facts | 分母と引用行を含む、日付付き記録としての主要な調査結果 |
site_report | あるドメインについて保存された監査結果 |
scan_site | 今すぐドメインを測定する |
census_stats | コーパス全体の集計 |
読み取りツールに認証は不要です。ストリーミング可能なHTTPを使用します。
インストール
npm i github:taylorsmithgg/crawl-census-client
pip install git+https://github.com/taylorsmithgg/crawl-census-client
使い方
import { politeFetch } from "crawl-census-client";
const r = await politeFetch("https://example.com/", { agent: "gptbot" });
if (r.skipped) console.log(r.verdict, r.reason); // disallow | refuse | pay
else process(await r.response.text());
from crawl_census import polite_fetch
r = polite_fetch("https://example.com/", agent="gptbot")
if r.skipped:
print(r.verdict, r.reason)
else:
process(r.body)
スキップは例外としてではなく、戻り値として返されます。ウェブ上ではスキップが通常の結果となるケースが多いため、クロールループはURLごとにtry/exceptで囲まずにスキップ数を集計できるべきです。
クロール前にキューを分割する
ホストごとに1回ではなく、ドメイン1,000件ごとに1回呼び出します。
const { crawl, skip, pay, unknown } = await partition(urls, { agent: "gptbot" });
p = partition(urls, agent="gptbot")
p.crawl, p.skip, p.pay, p.unknown
ファイルをそのまま使う方法もあります
メモリ内の拒否リストだけが必要なフェッチャーなら、ドメインごとの呼び出しはすべて省略できます。
curl https://crawlcensus.com/agents/gptbot/blocklist.txt # one domain per line, commented header
const sync = await syncBlocklist("gptbot"); // full list once
if (sync.blocked.has(host)) skip();
setInterval(() => sync.refresh(), 3600_000); // then deltas only, a few hundred bytes
sync = BlocklistSync("gptbot")
if host in sync: skip()
sync.refresh() # {'added': 3, 'removed': 1, 'size': 3310, 'cursor': ...}
差分フィードはhttps://crawlcensus.com/agents/<agent>/changes.json?since=<unix>で、各レスポンスにはnext_sinceが含まれます。そのため、長時間稼働するクローラーも、リストを再ダウンロードすることなく、1時間あたり数百バイトで最新の状態を保てます。
このファイルが対象とするのはrobots.txtのみです。ネットワーク境界での拒否とHTTP 402はリクエストごとの動作であり、引き続きpreflightまたはpoliteFetchが必要です。
クロールによってCensusにかかる負荷
推測ではなく、実測値です。20ホストを同時に取得すると、以前はドメインを1件ずつ指定して20回の事前確認呼び出しが必要でした。同じホストへのリクエストが同時に3回あった場合も、最初の検索が完了するまではキャッシュが役立たないため、3回必要でした。匿名利用の上限は1時間あたり240回なので、1回の呼び出しで25ホストを確認する場合、クローラーは240ホストで上限に達していました。
politeFetchは、処理を自動で共有するようになりました。同じティックで発行された検索はまとめて1回の呼び出しになり、同じホストへの同時検索は1つのリクエストを共有します。
| パターン | 以前 | 現在 |
|---|---|---|
| 20ホスト、同時実行 | 20回の呼び出し | 20件をまとめた1回の呼び出し |
| 1ホスト、URL 3件、同時実行 | 3回の呼び出し | 1回の呼び出し |
| 60ホスト、同時実行 | 60回の呼び出し | 3回の呼び出し(25 / 25 / 10) |
partitionしてから取得 | 2回の呼び出し | 1回の呼び出し |
batchSizeのデフォルトは25です。これはキーなしの場合の1回あたりの上限です。ProまたはDataキーを使えば、値を大きくできます。
batchWaitMsを設定すると、一度にではなく波状に到着する同時リクエストをまとめる時間を延長できます。デフォルトの0では、次のティックでフラッシュします。
オリジンが料金を提示した場合の支払い
pay判定には、オリジンが料金を提示した場合、その金額が含まれます。
const r = await politeFetch(url, { agent: "claudebot" });
if (r.verdict === "pay") console.log(r.price); // "USD 0.5", or null if none was quoted
知っておくとよい点が2つあります。HTTP 402を返すオリジンのほとんどは金額を提示しないため、priceは通常nullで、支払いの取り決めは別途行う必要があります。また、料金設定はクローラーごとに異なります。測定対象のコーパスでは、課金するオリジン213件のうち78件が、一部のエージェントには課金し、ほかのエージェントには無料でコンテンツを提供しています。そのため、リストにあるドメインが自分にも課金すると決めつけず、自分のトークンを使って確認してください。
2 種類の不明
partition は作業キューを crawl、pay、skip、unknown、undecidable に分割します。
最後の 2 つは似ていますが、意味は異なります。unknown は、そのドメインがまだ調査されていないことを意味します。送信すれば、次のパスで実際の判定が得られます。undecidable は、そのサイトの robots.txt が CrawlCensusBot を拒否しているため、今回の調査では今後も測定されないことを意味します。再試行は確実に無駄になり、各パスで不明な項目を再送信するループでは、それらが永遠に再送信されます。サーバーは measurable ブール値でこの違いを示します。reason の説明文ではなく、必ずこちらを参照してください。
const p = await partition(urls, { agent: "gptbot" });
await Promise.all(p.crawl.map(politeFetchOne));
if (p.unmeasured.length) await submitUnmeasured(p, { agent: "gptbot" });
// p.undecidable: read their robots.txt yourself. Asking us again cannot help.
送信を別の呼び出しにしているのは意図的です。検索に見える処理の最中にひそかに POST するライブラリは行儀が悪く、キューの枠をいつ使うかは自分で選ぶべきです。
役に立たないものをすべてスキップする
拒否リストは対象の半分にすぎません。最新の調査結果では、robots.txt による拒否だけをスキップするクローラーは、robots.txt では許可されているもののエッジで拒否されるドメインや、HTTP 402 を返すドメインに対して、各パスで約 2,900 件のリクエストを余分に行います。PerplexityBot では、そうした対象のほうが拒否リストより多くなっています。こうした取得は何も返さず、毎回ラウンドトリップのコストが発生します。
const skip = await syncSkipList("gptbot");
if (skip.has(host)) continue; // disallowed, refused at the edge, or priced
skip.why(host); // "disallow" | "pay" | "refuse" | null
setInterval(() => skip.refresh(), 3600_000);
| エージェント | 拒否リスト | 追加でスキップ可能 | 合計 |
|---|---|---|---|
| GPTBot | 3,542 | 2,944 | 6,486 |
| ClaudeBot | 3,169 | 3,194 | 6,363 |
| PerplexityBot | 1,128 | 3,658 | 4,786 |
3 つの集合は内部で分けて管理されているため、変更があれば該当する集合だけが更新されます。why() は preflight と同じ優先順位に従います。価格より拒否が優先されます。価格は許可を意味しないためです。
拒否リストを最新に保つ
syncBlocklist / BlocklistSync はリストを一度ダウンロードし、変更があった項目だけを反映します。
リストには、作成時点の変更フィード上の正確な位置が、x-cursor ヘッダーと # cursor: コメントで示されています。クライアントはそれを読み取り、その位置から再開するため、スナップショットと最初のポーリングの間に抜けが生じず、サーバーと時計が一致していることにも依存しません。秒単位のポーリングでは、1 秒内の位置を表せません。また、クロールバッチでは 1 秒の間に何十ものイベントが書き込まれるため、秒単位で再開すると、その残りが失われる可能性があります。実際の測定では、同じ秒に発生した 3 件の変更のうち最初の変更の後から再開した場合、カーソルを使えば残りの 2 件を取得できましたが、秒単位ではどちらも取得できませんでした。
const sync = await syncBlocklist("gptbot"); // cursor comes from the list itself
if (sync.blocked.has(host)) skip();
setInterval(() => sync.refresh(), 3600_000); // a few hundred bytes per poll
refresh() は、リストに含まれるものが robots の状態遷移だけであるため、それだけをリストに反映します。エッジによる拒否、新しい価格、llms.txt の変更は other として返されるので、個別に対応してください。以前のバージョンでは、こうしたドメインが拒否リストから削除されていたため、クローラーは拒否され始めたばかりの対象を再び取得していました。
判定
各判定の正式な定義、つまり意味、クローラーに求められる対応、再確認によって結果が変わる可能性の有無は、/api/v1/verdicts のデータとして公開されています。以下の一覧は要約です。両者が異なる場合はエンドポイントが正しく、このファイルが古くなっています。
politeFetch はデフォルトで disallow、refuse、pay をスキップします。これはエンドポイントの算出値である do_not_fetch セットに相当します。ここに内容を複製しているのは意図的です。クロールループで判断するためにネットワークリクエストは不要であるべきです。また、テストで両者を比較し、気づかないうちに食い違うことがないようにしています。
| 判定 | 意味 | デフォルトの動作 |
|---|---|---|
allow | robots.txt がこのエージェントを許可しており、そのユーザーエージェントを指定した実際のリクエストに応答があった | 取得 |
disallow | サイトのルートで robots.txt がこのエージェントを拒否している | スキップ |
refuse | robots.txt は許可しているものの、エッジでは拒否された。この許可は実質的なものではない | スキップ |
pay | オリジンが HTTP 402 で応答した。このエージェントへの提供には商用条件が適用される | スキップ |
unknown | 回答を得るには測定が古すぎる | 取得 |
onPay: "fetch"(on_pay="fetch")を指定すると、ペイウォールのデフォルト動作を上書きできます。これは明示的なオプトインであり、結果の paidRouteOverridden に記録されるため、ログで確認できます。
劣化はしますが、停止はしません
国勢調査にアクセスできない場合、すべての判定が unknown になり、クロールは通常どおり続行されます。サードパーティの障害で、パイプラインが停止することは決してありません。まさにこの状況を検証するライブテストがあります。
エージェントについて公開する情報
const p = await agentProfile("claudebot");
// robots disallow rate, edge refusal rate, operator page, correction channel
数値に誤りがある場合は、その回答内とオペレーターページに訂正窓口を記載しています。レジストリの情報は異議なく訂正されます。測定結果に異議がある場合は、ひそかに修正するのではなく、基となるスキャン記録とともに異議の内容を併記して公開します。
制限
匿名での事前チェックは1回につき25ドメイン、Pro キーでは200ドメイン、Data キーでは1,000ドメインです。apiKey を渡してください。詳細は https://crawlcensus.com/for-crawlers をご覧ください。
テスト
node test.mjs は、意図的にライブの国勢調査を対象に実行します。このクライアントの価値は判定が実情と一致するかどうかにあります。モックを使ったテストでは、モックが自身と一致することしか検証できません。
MIT。データは CC BY 4.0 です。「Source: Crawl Census (crawlcensus.com)」と記載してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。