Crawl4AI には、ずっとつきまとっている“都市伝説”みたいな話があります。サイトのHTML構造が変わってもデータを見つけ直してくれる、自己修復型の知能があるという噂です。けれど、実際は違います。それは別のツールで、気になるなら Scrapling の話です。Crawl4AI はもっと具体的で、ちゃんと正しく理解したほうが価値が見えてきます。つまり、ヘッドレスブラウザに Markdown 変換器を組み合わせ、さらに CSS/XPath の抽出機能を足したものです。
私は一通りテストをして、静的ページ、JavaScript で描画されるカタログ、わざと壊した 500 エラーページ、そして小規模な深いクロールを試しました。中核部分は本当に優秀です。その一方で、セットアップの重さ、深いクロール時の挙動、そして紛らわしいエラーメッセージのような、見落とされがちな部分こそ、このレビューでしっかり掘り下げています。以下はすべて、実際にやったテストに基づく暫定評価であって、最終的な benchmark ではありません。触れていない項目について勝手に語られないよう、テストしていない点は明記します。
Crawl4AIの正体と、誤解されている“何か”ではない理由
宣伝文句を外してみると、Crawl4AI は大きく 3 つの要素が重なったツールです。
まず、本物のブラウザです。内部では Playwright を動かし、さらに Patchright というステルス対応の派生版も使って、Chrome と同じようにページを読み込みます。JavaScript を実行し、DOM を組み立て、必要なら待機してからコンテンツを取得します。ここが重要です。生の HTML を落として終わり、という HTTP クライアントではありません。実際のレンダリングエンジンを動かしています。
次に、Markdown 生成器です。ページが描画されると、Crawl4AI は DOM を Markdown に変換します。これは LLM や RAG パイプラインが扱いやすい形式です。メンテナーがこのプロジェクトを LLM に優しいクローラ と位置づけているのはまさにこのためで、URL を渡せば、モデルが推論しやすいテキストが返ってきます。
3つ目は、構造化抽出です。説明文ではなくきれいな JSON が欲しいなら、JsonCssExtractionStrategy を通して、CSS あるいは XPath のセレクタをフィールド名に対応づけたスキーマを渡します。するとレコードが返ります。(LLM ベースの抽出経路もありますが、API キーが必要で、今回は試していないので、挙動を知っているふりはしません。)
そして、ここが大事なポイントで、“adaptive intelligence” の噂が外している点です。スキーマは静的で、手で書くものです。たとえば、商品名は .product-card h3、価格は .price にあると Crawl4AI に伝えます。もし明日サイト側がクラス名を変えたら、セレクタは壊れたままになります。自動修復はありません。曖昧な再マッチもありません。正体は、ブラウザ、変換器、そして自分で保守するセレクタです。それ以上でも、それ以下でもありません。最初にここを理解しておけば、別リポジトリにある機能を期待してがっかりすることもありません。
実際に触るプリミティブの名前も素直です。AsyncWebCrawler がエンジン、BrowserConfig がブラウザ設定、CrawlerRunConfig が 1 回分の実行設定です(後で触れる wait_for もここに含まれます)。非同期ファーストの Python API ですが、名前の意味がつかめれば読みやすいです。
参考までに、このリポジトリは 2026-07-07 時点で 71,259 stars、7,326 forks、Apache-2.0 で、リリースは v0.9.0 です (unclecode/crawl4ai)。スター数は変わるので、これはライブ値ではなくスナップショットとして受け取るべきですが、それでもかなり使われている、しかも寛容なライセンスのプロジェクトだと分かります。週末の思いつきで作った実験ではありません。
セットアップ:2つのフルブラウザ環境がディスクに降ってくる場面
Crawl4AI が軽量ライブラリの顔をやめるのが、インストール時です。しかも、ほとんどのレビューがここをあまり書きません。
pip での導入自体はスムーズです。pip install -U crawl4ai は問題なく完了しました。しかも、ドキュメントでは 3.10 以上が目安 なのに、手元に 3.10〜3.13 のランタイムがない状態で Python 3.14.2 にも入ります。先端寄りの環境を使っている人には、これはかなりいい兆候です。
そのあと crawl4ai-setup を実行すると、そこでディスク容量が一気に削られます。

セットアップでは 1 つのブラウザを入れるわけではありません。Playwright と Patchright、2 つのフルスタックを落としてきます。ログにはさらに Chrome for Testing、FFmpeg、Headless Shell まで含まれています。これが“本物のブラウザを使うツール”の代償です。ブラウザはどこかに置かなければならず、ここではそれがマシン上に 2 重で入ります。SSD 容量がきついノートPCや、1MB 単位で削りたい軽量コンテナを作るなら、最初から織り込んでおくべきです。純粋な HTTP パーサーのフットプリントではありませんし、今後もそうなることはありません。
良い点として、ツール側は自分の健全性にかなり正直です。crawl4ai-doctor はちゃんと動いて、https://crawl4ai.com を 14.65 秒でクロールし、ブラウザ経路が最後まで通ることを確認してくれました。実ページを描画する内蔵の doctor コマンドはありがたいです。「インストールは成功したのか?」という問いに、きちんとした答えが返るからです。
つまりセットアップの評価ははっきり二面性があります。Python 側はなめらかで寛容、ブラウザ側は重い。この両方が同時に真実で、導入前に知っておくべきです。
実地テスト:何がうまくいったか、数値つきで
私はローカルに、正解データが分かっているテスト用サイトを用意しました。静的な商品一覧、JS で描画される商品一覧、わざと余計な装飾を入れた記事、壊れた 500 ページ、小さなリンクグラフです。そこに加えて、公開デモサイト 2 つも使いました。結果は以下の通りです。

静的ページ:完全勝利。 公式クイックスタートで example.com を対象にすると、Markdown は 1.81 秒で返ってきました。ローカルの静的カタログでは、Markdown が期待していた商品名を 6/6 すべて保持し、CSS スキーマ抽出でも 6 件 を JSON として取得できました。項目は name、category、price、rating、detail URL で、どれも欠けなし。まったく問題ありません。
動的ページ:正しく待てば、これも問題なし。 ここが大事な条件です。JS で描画されるカタログでは、wait_for="css:.product-card" を実行設定に足すと、Markdown でもスキーマ抽出でも 8/8 の商品を回収できました。公開サイト quotes.toscrape.com/js でも、JavaScript で注入された引用文が描画され、ブラウザが本当に中身を描いた証拠として使えるスクリーンショットも保存できました。ここでの “dynamic” は飾りではありません。本当にブラウザが描画しています。ただし、何を待つかは自分で指定する必要があります。wait_for を省くと、半分だけできたページを拾うことになります。

バッチ処理:ちゃんと動く。 6 つのローカル商品 URL に対する arun_many() は、1 回の並列実行で 6/6、すべて 200 を返しました。サンプル数は少ないですが、並列実行の経路は期待通りです。
実サイトでの Markdown 量。 公開サイト Books to Scrape のトップページに対しては、1 回の呼び出しでライブページから 13,476 文字 の Markdown を生成しました。実際のカタログから、LLM 向けテキストがどれくらい取れるかを実感できる数字です。

ここからは、うまくいく範囲を越えたときに見えてくる粗い部分です。
生の Markdown は、意図通り広く拾う。 記事用のテストページでは、Crawl4AI はタイトルと本文 3 段落 3/3 を取得しましたが、それだけでなく、ナビゲーションテキスト、関連記事ブロック、偽の購読案内、フッターも一緒に拾いました。これは欠陥ではありません。生の Markdown 変換とはそういうものです。レンダリングされたページ全体が、そのまま Markdown になります。きれいな記事だけが欲しいなら、公式ドキュメント の通り、コンテンツフィルタを明示的に有効化します。PruningContentFilter はテキスト密度とリンク密度でノードをスコアリングし、不要部分を落とします。BM25ContentFilter はクエリに対して順位づけします。今回はこれらを使っていないので、クリーンさの数値は付けません。ただ、考え方は明快です。生の Markdown は広く拾うデフォルト、きれいな Markdown はフィルタをオンにして得るものです。設定ゼロで編集済みの記事品質を期待してはいけません。
500 ページは、ちょっと嘘をついた。 わざと壊した HTTP 500 ページを Crawl4AI に渡しました。success=false とステータス 500 は正しく返りましたが、エラーメッセージは「Blocked by anti-bot protection: Structural: minimal_text on small page.」でした。実際にはアンチボットの壁はありません。単に表示テキストがほとんどない小さなエラーページで、Crawl4AI の構造ヒューリスティックが薄い本文を見て、アンチボットと判断してしまったのです。大規模運用する人への教訓は明確です。“anti-bot” という文言をそのまま信じないこと。ステータスコードと実際の状況を見てから、サイトが本当に妨害しているのか判断してください。単に小さいページなだけ、ということもあります。

深いクロールは、待機設定を自動継承しない。 これだけは、クロールを組む前に知っておきたかった点です。明示的な wait_for を付けて動的ページを直接クロールしたときは、8/8 で完璧でした。しかし、BFS の深いクロール にホームページからリンクを見つけさせて辿らせると、5 ページを発見し、3 ページ成功、2 ページ失敗 でした。失敗の 1 つは、さっきの動的カタログページです。これは明示的に待てば問題なく動くページです。ところが深いクロールでは、レンダリング前の 45 文字しか見えず、ページが薄すぎると判断され、JavaScript の描画が終わる前に、同じ紛らわしい「anti-bot」メッセージで止まりました。
ここから分かることははっきりしています。「Crawl4AI は動的ページに対応している」は本当です。しかし、「深いクロールが見つけたすべての動的ページを自動で待ってくれる」は違います。これは別々に用意された機能、つまりページ単位の待機と深いクロール戦略であって、自動では混ざりません。深いクロールで JS 依存ページを扱うなら、待機設定をクロール構成にきちんと入れる必要があります。これはバグというより設定の問題ですが、“発見したリンクにもそのまま効くだろう” と考えると、かなり痛い目を見ます。
長所と短所、曖昧さなしで
評価できる点:
- 1つのライブラリでかなり広くカバーできる。レンダリング済み Markdown、構造化 JSON 抽出、スクリーンショット、バッチクロール、深いクロールまで、4つのツールをつなぎ合わせなくて済む。
- 静的抽出は堅牢。私のテストでは Markdown の回収率 6/6、構造化レコード 6/6 で、しかも高速かつ欠損なし。
- 動的レンダリングは本当に動く。実際のブラウザが描画しているからこそで、明示的な待機付きで 8/8、スクリーンショットでも確認できた。
- Apache-2.0 ライセンスで商用利用しやすく、v0.9.0 として継続的に出ている、コミュニティも大きいプロジェクト。
crawl4ai-doctorが実ページを描画して、インストールが本当に動いているか確認できる。
コストになる点:
- 初回セットアップが重い。2 つのブラウザスタックに加え、FFmpeg と Headless Shell までディスクに入る。制約のある環境ではかなりの負担。
- コンテンツフィルタを使わない限り、生の Markdown には余計な装飾が混ざる。きれいな出力はデフォルトではなく、明示的な手順。
- 深いクロールでは、動的ページ向けの待機設定を自動では適用しない。途中で見つけた JS ページは、追加設定なしだと失敗しうる。
- エラーメッセージが紛らわしいことがある。薄い 500 ページが、何もブロックしていないのに「anti-bot protection」と表示された。
- 自己修復セレクタはない。CSS/XPath スキーマは静的で、HTML が変わったら自分で保守する必要がある。
Crawl4AI は誰向けか、誰は別の道を選ぶべきか
使うべき人: RAG やエージェントのパイプラインを作っていて、同じレンダリング済みページから LLM 向け Markdown と構造化 JSON の両方が欲しい開発者です。対象サイトが JavaScript 多めで、明示的な待機設定を書くことに抵抗がなく、自前のインフラで本物のヘッドレスブラウザを回すことに納得できるなら、Crawl4AI はかなり相性が良いです。モデル用の Markdown とデータベース用のスキーマを 1 つの Apache-2.0 ライブラリで扱えるのは、やっぱり便利です。
見送るべき人: ミリ秒単位で静的 HTML を取るだけの軽量 HTTP パーサーが欲しいなら、Crawl4AI は重すぎます。ブラウザのダウンロードだけでも面倒に感じるはずです。ディスクや帯域が厳しい場合、あるいは最小構成のコンテナに入れたい場合も向きません。そして、自己修復セレクタを探しているなら絶対に違います。それは本当にある機能ですが、このツールの機能ではありません。
マネージド API の居場所 — Thunderbit の視点
ここまでの話は、自分でブラウザを運用したい前提です。それは正当な選択ですし、多くのチームにとっては正解でもあります。完全な制御、呼び出しごとのコストゼロ、最後まで自分のコード。ですが、その代わりに何を引き受けるのかを、はっきり言葉にしておく価値があります。というのも Thunderbit では、あえて逆のトレードオフで開発者向けスタックを作っているからです。ブラウザ、アンチボット対応、JavaScript 描画を、あなたのマシンから完全に切り離します。
対応関係はかなり近いので、素直に比べられます。POST /distill エンドポイントは、Crawl4AI の Markdown パスと同じように、ページを受け取って LLM 向けのきれいな Markdown を返します。ただし JS 描画とアンチボット層は、インストールしたブラウザではなく、こちら側で処理します。POST /extract エンドポイントは構造化側を担い、定義したスキーマに対して JSON を返します。wait_for を手で調整する代わりに、renderMode(none、basic、full)を切り替える形です。どちらにもバッチ版があります。MCP サーバー もあり、thunderbit_distill、thunderbit_extract、無料の thunderbit_suggest_fields を Claude や Cursor のエージェントから直接呼べます。さらに、ターミナル・CI・cron 向けに npx @thunderbit/thunderbit-cli も用意しています。
違いは、重さを誰が持つかです。Crawl4AI は無料・オープンソース・セルフホストで、その運用負荷——ブラウザのダウンロード、深いクロールの配線、動かすマシン——はあなたが背負います。Thunderbit の開発者向けスタックはマネージド API なので、その負荷は私たちの側が持ち、コストは呼び出し単位に移ります。どちらが常に優れているわけではありません。すべての層を自分で管理して、リクエストごとの費用を払いたくないなら Crawl4AI です。ブラウザ運用の面倒を手放して、エンドポイントを呼びたいなら、マネージド路線が向いています。API の裏側には、10万人超のユーザーが使う拡張機能と同じエンジンが動いているので、試作品レベルではありません。
このカテゴリ全体を比べたいなら、AI web scraping に関する自社記事や、オープンソースの GitHub スクレイパーを横並びで検証した記事 のほうが、ここで書ききれない部分まで踏み込んでいます。
結論:Crawl4AI を使うべきか?
はい。もしあなたが、同じレンダリング済みページから LLM 向け Markdown と構造化 JSON の両方を取り出したくて、RAG やエージェント向けに構築しており、自前のインフラ上で本物のヘッドレスブラウザを動かすことを受け入れられるなら、使う価値があります。私のテストでは、中核部分は約束どおり動きました。静的抽出は 6/6、明示的な待機を入れた動的ページは 8/8、ライブのカタログからは 13,476 文字の Markdown、バッチクロールも問題なし。しっかりしたライセンスで、活発に保守されている、実務向けのツールです。
ただし、次の 3 つは最初から理解しておいてください。セットアップで 2 つのブラウザスタックがディスクに入ること、深いクロールでは見つけた動的ページを自動では待たないこと、薄いエラーページが誤って「anti-bot」と表示されることです。どれも致命的ではありません。ですが、奇跡を期待するのと、実際のツールを使うのとでは意味が違います。ここでの正体は、繰り返しますが、ブラウザ、Markdown 変換器、そして自分で保守するセレクタです。それとして理解すれば、ライブページをモデルが使えるテキストに変える方法としては、かなり優秀な部類です。
これは 1 回のテスト実行に基づく暫定レビューです。1,000 ページ規模のクロールはしていませんし、コンテンツフィルタも、LLM 抽出経路も、Docker のサーバーモードも触っていません。私の中での評価は「かなり良いが、宿題は残っている」という段階として受け取ってください。また、メタデータを引用する前には、スター数とバージョンを必ず再確認してください。どちらも変わるからです。
Webデータ抽出に Thunderbit を試す Get Started Free
よくある質問
Crawl4AI に自己修復型や適応型のセレクタはありますか? いいえ。これがいちばん多い誤解です。Crawl4AI は、あなたが書いて保守する静的な CSS/XPath スキーマを使います。サイトがセレクタ依存のクラス名を変えたら、あなたがスキーマを直すまで抽出は壊れたままです。適応的に自分で見つけ直すセレクタは、別のツール(Scrapling)の機能であり、Crawl4AI ではありません。
Crawl4AI を動かすのにフルブラウザは必要ですか?
実質的には必要です。中核価値が本物のブラウザによる JavaScript 描画だからで、crawl4ai-setup は Playwright と Patchright の 2 つのブラウザスタックに加えて、FFmpeg と Headless Shell をダウンロードします。ブラウザの痕跡がまったくない小さな HTTP 専用パーサーが欲しいなら、Crawl4AI は形が違います。軽量フレームワークを選んだほうがよいでしょう。
Crawl4AI が、ブロックされていないページに対して「anti-bot protection」と出したのはなぜですか? 表示テキストが少ないページを構造ヒューリスティックが検知し、その際に anti-bot protection という文言が出るためです。私のテストでは、意図的な HTTP 500 ページが、何もブロックしていないにもかかわらず、そのラベルになりました。サイトが本当に妨害していると結論づける前に、必ずステータスコードと実際の状況を確認してください。単に薄いページ、あるいは壊れたページなだけのこともあります。
Crawl4AI の深いクロールは JavaScript ページを自動で処理しますか?
自動ではありません。明示的な wait_for を付けた直接クロールでは、動的ページは 8/8 で問題なく処理できました。しかし、同じページを深い BFS クロールで見つけた場合は失敗しました。5 ページ見つかって 3 成功、2 失敗です。JavaScript の描画を待たずにページが薄いと判断されたからです。深いクロールで動的ページを対象にするなら、待機設定を明示的に組み込む必要があります。
Crawl4AI は Thunderbit のようなマネージドスクレイピング API とどう違いますか?
Crawl4AI は無料・オープンソース・セルフホストです。ブラウザとインフラは自分で運用し、呼び出しごとの費用はかかりません。Thunderbit の開発者向けスタック(Markdown 用の /distill、構造化 JSON 用の /extract、さらに MCP と CLI)はマネージド API で、レンダリング、アンチボット対応、ブラウザ運用は私たち側で処理し、料金は呼び出し単位です。選択は、完全な制御とゼロの従量課金か、運用負荷を外に逃がすか、という違いです。


