~/utility/rag-web-crawler
RAG Web Crawler — WebページをMarkdownとテキストチャンクに
公開Webページを、クリーンなMarkdown、プレーンテキスト、出典URLと文字位置付きの重なり合うテキストチャンクに変換。そのままRAG用に埋め込めます。
RAGデータ
TypeScriptMozilla ReadabilityjsdomTurndown
グローバル
カテゴリutility / RAGデータ
言語TypeScript
スタックTypeScript, Mozilla Readability, jsdom, Turndown
マーケットグローバル
出力クリーンでRAG対応のJSON
主な機能
各ページからクリーンなMarkdownとプレーンテキストを出力。見出し、リスト、リンク、コードブロック、シンプルな表を保持
そのまま埋め込めるチャンク。互いに重なり、できるだけ段落や文の切れ目で終わり、それぞれに安定したid、出典URLとタイトル、引用用の正確な文字位置が付きます
本文を優先:メニュー、ヘッダー、フッター、サイドバーは除外し、指定したその他の要素もCSSセレクターで取り除けます
各サイト内のリンクを最大5階層までたどり、各ページは一度だけ取得
URLの代わりに検索も:クエリの検索結果の各ページを開始URLと同じようにクロール(Apifyの有料プランが必要)
デフォルトでrobots.txtを遵守し、同じサイトへのリクエストは間隔を空けて送信
ページは英語、中国語など元の言語のまま、翻訳しません
ページごとにステータスとエラーコードを、実行ごとに件数と停止理由を含むサマリーを記録
活用例
- ドキュメントやヘルプセンターのページから、RAGチャットボットのナレッジベースを構築
- 引用できる最新のWebページにAIエージェントの回答を根拠付ける
- 記事の一覧をセマンティック検索用の埋め込みに変換
- あるテーマの検索で見つかったページを、元の言語のまま収集
- ベクトルストアを定期的に更新。ページが変わらない限りチャンクのidも変わりません
- ApifyのMCPサーバー経由で、AIエージェントにWebページをMarkdownで提供
入力パラメータ
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
startUrls | array | 任意 | クロールする公開ページのURL(最大1,000件) |
query | string | 任意 | 検索結果のページをクロールする検索クエリ(Apifyの有料プランが必要) |
queries | array | 任意 | 追加の検索クエリ。query と統合されます |
maxResultsPerQuery | number | 任意 | クエリごとにクロールする検索結果数(デフォルト5、最大50) |
maxPages | number | 任意 | 1回の実行で予定する異なるページの最大数(デフォルト20、最大1,000) |
maxDepth | number | 任意 | 各サイト内でたどるリンクの階層数(デフォルト0 = 開始URLのみ、最大5) |
maxConcurrency | number | 任意 | 同時に処理するページ数(デフォルト3) |
maxSearchRequests | number | 任意 | 1回の実行あたりの検索リクエスト数。リトライを含む(デフォルト10、0 = 検索なし) |
maxFetchRequests | number | 任意 | 1回の実行のすべてのネットワーク試行。robots.txtとリトライを含む(デフォルト100) |
requestTimeoutSecs | number | 任意 | 各リクエストのタイムアウト(秒、デフォルト30) |
maxResponseBytes | number | 任意 | 受け付けるページレスポンスの最大サイズ(デフォルト2 MiB) |
maxContentChars | number | 任意 | ページごとに保持するテキストの最大長(文字数、デフォルト50,000) |
maxOutputBytes | number | 任意 | 1回の実行の出力合計(デフォルト20 MiB) |
respectRobotsTxt | boolean | 任意 | まず各サイトのrobots.txtを確認(デフォルトでオン) |
onlyMainContent | boolean | 任意 | ページの本文だけを残す(デフォルトでオン) |
removeSelectors | array | 任意 | 抽出前に取り除く要素のCSSセレクター |
chunkSize | number | 任意 | チャンクの長さ。トークンではなく文字数(デフォルト1,000) |
chunkOverlap | number | 任意 | 隣り合うチャンクが共有する文字数(デフォルト150) |
出力例
実際の実行で保存された1ページです。テキストは短縮し、5つのチャンクのうち1つだけを示しています。
1{
2 "schemaVersion": "1.0",
3 "url": "https://www.w3.org/WAI/tutorials/tables/one-header/",
4 "title": "Tables with One Header",
5 "description": "Accessibility resources free online from the international standards organization: W3C Web Accessibility Initiative (WAI).",
6 "languageCode": "en",
7 "canonicalUrl": "https://www.w3.org/WAI/tutorials/tables/one-header/",
8 "markdown": "# Tables with One Header\n\nin [Tables Tutorial](https://www.w3.org/WAI/tutorials/tables/)\n\n## Overview\n\n…",
9 "text": "Tables with One Header\n\nin Tables Tutorial\n\nOverview\n\nThis page covers tables that have one simple header for rows or one simple header for columns. …",
10 "chunks": [
11 {
12 "id": "495cb4e58e13bbf9b5cdbe922f7ea652973ca4dfda61b952aaa021db045a450c",
13 "index": 0,
14 "text": "Tables with One Header\n\nin Tables Tutorial\n\nOverview\n\nThis page covers tables that have one simple header for rows or one simple header for columns. …",
15 "startChar": 0,
16 "endChar": 988,
17 "sourceUrl": "https://www.w3.org/WAI/tutorials/tables/one-header/",
18 "title": "Tables with One Header"
19 }
20 ],
21 "contentTruncated": false,
22 "sources": [],
23 "crawl": {
24 "depth": 0,
25 "httpStatusCode": 200,
26 "loadedAt": "2026-10-19T07:03:53.643Z",
27 "contentType": "text/html",
28 "renderingMode": "http",
29 "extractionMethod": "main"
30 }
31}
チャンクの位置は text のUnicodeコードポイントで数えます。実行ごとに、ページごとのステータスとエラーコードを記録した REQUESTS と、件数、停止理由、課金されたイベントを含む実行サマリーの OUTPUT も書き出されます。
ヒント
idをベクトルストアのレコードIDに使いましょう。 ページとチャンク設定が変わらない限り実行をまたいでも同じなので、定期実行でidごとに書き込めば、コピーが増えずに置き換わります。- まずは少ないページから。
maxPagesやmaxDepthを増やす前に対象ページのMarkdownを確認し、関連リンク枠などの残りはremoveSelectorsで取り除きましょう。 REQUESTSもDatasetと一緒に確認しましょう。 実行が成功しても一部のページがスキップや失敗になっていることがあり、それぞれに理由が記録されます。
よくある質問
一般的なWebスクレイパーとの違いは?
セレクターではなく、URLか検索クエリを渡すだけです。各ページの本文をMarkdownとプレーンテキストで保存し、テキストをそのまま埋め込めるチャンクに分割します。各チャンクにはページのURL、タイトル、正確な文字位置が付くので、回答に出典を示せます。
APIキーは必要ですか?
クロールにも検索にも、外部のAPIキーは不要です。Apifyアカウントが必要で、ApifyのAPIからActorを呼び出すときはApifyトークンを使います。
JavaScriptはレンダリングできますか?
できません。ページはHTTPで読み込むため、テキストの表示にJavaScriptが必要なページはNO_CONTENTで失敗するか、不完全な内容になることがあります。まず対象ページをいくつか試してください。
どんなページを読めますか?
公開されているHTML、Markdown、プレーンテキストのページです。ログイン、Cookie、ペイウォール、CAPTCHA、プロキシ、PDF、画像は対象外で、プライベートネットワークのアドレスや認証情報を含むURLは拒否されます。
Webサイトをクロールしても問題ありませんか?
公開されている個人情報以外のデータのクロールは一般に合法ですが、ページの内容は著作権で保護されていることが多く、利用規約でクロールを制限しているサイトもあります。クローラーはデフォルトでrobots.txtに従います。収集した内容の使い方はご自身の責任となります。