web-scraper について
Web Scraperは、ウェブサイトをクロールし、抽出したテキストをローカルに保存するコマンドラインスキルおよびスクリプトです。ページ数やドメインを制限した再帰・並行取得とノイズ除去に対応し、静的HTMLのみを扱います。
主な機能
- 01リンクをたどる再帰クロール
- 02HTTPリクエストの並行処理
- 03ページ数とドメインの制限
- 04本文テキストの抽出とフィルタリング
- 05URL構造に沿った出力ディレクトリ
- 06セッション情報とエラーログの記録
活用シーン
- 01ドキュメントサイトのアーカイブ
- 02関連ドメインからのテキスト収集
- 03ページ数を制限した大規模サイトのサンプル取得
- 04調査用ローカルテキスト集の作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ igosuki/ claude-skills --skill web-scraperインストール後、Claude Code で/web-scraperを入力して読み込まれたか確認します。
同梱ファイルscripts/scrape.py
詳細
Web Scraper
概要
並行処理でウェブページを再帰的にスクレイピングし、リンクをたどりながらクリーンなテキストコンテンツを抽出します。スクレイパーはURLの重複を自動的に処理し、URL構造に基づいて適切なディレクトリ階層を作成し、不要なコンテンツを除外して、ドメインの境界を守ります。
このスキルを使用する場面
ユーザーから次のようなリクエストがあった場合に、このスキルを使用します。
- ウェブサイトのコンテンツをスクレイピングする
- オンラインソースからドキュメントをダウンロードする
- ウェブページから大規模にテキストを抽出する
- 情報を収集するためにウェブサイトをクロールする
- ウェブコンテンツをローカルにアーカイブする
- リンク先のページをたどってダウンロードする
- ウェブソースから調査データを収集する
- ウェブサイトからテキストデータセットを構築する
前提条件
必要な依存関係をインストールします。
pip install aiohttp beautifulsoup4 lxml aiofiles
これらのライブラリは、次の機能を提供します。
aiohttp- 並行リクエストに対応した非同期HTTPクライアントbeautifulsoup4- HTMLの解析とコンテンツの抽出lxml- 高速なHTML/XMLパーサーaiofiles- 非同期ファイルI/O
主な機能
1. 単一ページの基本的なスクレイピング
リンクをたどらずに、単一のページをスクレイピングします。
python scripts/scrape.py <URL> <output-directory> --depth 0
例:
python scripts/scrape.py https://example.com/article output/
指定されたページのみをダウンロードし、クリーンなテキストコンテンツを抽出して、output/example.com/article.txt に保存します。
2. リンクをたどる再帰的なスクレイピング
ページをスクレイピングし、指定した深さまでリンクをたどります。
python scripts/scrape.py <URL> <output-directory> --depth <N>
例:
python scripts/scrape.py https://docs.example.com output/ --depth 2
深さのレベル:
--depth 0- 開始URLのみ--depth 1- 開始URLと、そのページ上のすべてのリンク--depth 2- 開始URL、リンク、およびリンク先ページで見つかったリンク--depth 3+- 指定した深さまでリンクをたどり続けます
3. ページ数の上限設定
最大ページ数を設定して、過剰なスクレイピングを防ぎます。
python scripts/scrape.py <URL> <output-directory> --depth 3 --max-pages 100
例:
python scripts/scrape.py https://docs.example.com output/ --depth 3 --max-pages 50
次の用途に便利です。
- 全体の実行前にスクレイパーの設定をテストする
- リソースの使用量を制限する
- 大規模なサイトのコンテンツをサンプリングする
- レート制限を守る
4. 並行処理
同時リクエスト数を制御して、スクレイピングを高速化します。
python scripts/scrape.py <URL> <output-directory> --concurrent <N>
例:
python scripts/scrape.py https://docs.example.com output/ --depth 2 --concurrent 20
デフォルトでは、同時リクエスト数は10です。スクレイピングを高速化するには増やし、リソースの使用を抑えたい場合は減らしてください。
ガイドライン:
- 小規模なサイトや応答の遅いサーバー:
--concurrent 5 - 中規模のサイト:
--concurrent 10(デフォルト) - 大規模で高速なサイト:
--concurrent 20-30 - サーバーのリソースに配慮してください
5. ドメイン制限
デフォルトでは、スクレイパーは開始URLと同じドメイン上のリンクのみをたどります。この動作は制御できます。
同じドメインのみ(デフォルト):
python scripts/scrape.py https://example.com output/ --depth 2
外部リンクをたどる:
python scripts/scrape.py https://example.com output/ --depth 2 --follow-external
許可するドメインを指定する:
python scripts/scrape.py https://example.com output/ --depth 2 --allowed-domains example.com docs.example.com blog.example.com
次のような場合は、--allowed-domains を使用します。
- ドキュメントが複数のサブドメインに分かれている
- 関連する複数のドメインにコンテンツがまたがっている
- 信頼できる特定のドメインに対象を限定したい
6. 複数の開始URL
複数の開始地点から同時にスクレイピングします。
python scripts/scrape.py <URL1> <URL2> <URL3> <output-directory>
例:
python scripts/scrape.py https://example.com/docs https://example.com/guides https://example.com/tutorials output/ --depth 2
すべての開始URLは、同じ設定(深さ、ドメイン制限など)で処理されます。
7. リクエスト設定
HTTPリクエストの動作をカスタマイズします。
python scripts/scrape.py <URL> <output-directory> --user-agent "MyBot/1.0" --timeout 60
オプション:
--user-agent- カスタムUser-Agentヘッダー(デフォルト:"Mozilla/5.0 (compatible; WebScraper/1.0)")--timeout- リクエストのタイムアウト時間(秒)(デフォルト:30)
例:
python scripts/scrape.py https://example.com output/ --depth 2 --user-agent "MyResearchBot/1.0 (+https://mysite.com/bot)" --timeout 45
8. 詳細出力
詳細なログを有効にして、スクレイピングの進行状況を確認します。
python scripts/scrape.py <URL> <output-directory> --verbose
詳細モードでは、次の情報が表示されます。
- 取得中の各URL
- 保存に成功したファイルのパス
- エラーとタイムアウト
- 詳細なエラー情報
出力構造
ディレクトリ階層
スクレイパーは、URL構造を反映したディレクトリ階層を作成します。
output/
├── example.com/
│ ├── index.txt # https://example.com/
│ ├── about.txt # https://example.com/about
│ ├── docs/
│ │ ├── index.txt # https://example.com/docs/
│ │ ├── getting-started.txt
│ │ └── api/
│ │ └── reference.txt
│ └── blog/
│ ├── post-1.txt
│ └── post-2.txt
├── docs.example.com/
│ └── guide.txt
└── _metadata.json
ファイル形式
スクレイピングした各ページは、次の構造を持つテキストファイルとして保存されます。
URL: https://example.com/docs/guide
Title: Getting Started Guide
Scraped: 2025-10-21T14:30:00
================================================================================
[Clean extracted text content]
メタデータファイル
_metadata.json には、スクレイピングセッションの情報が含まれます。
{
"start_time": "2025-10-21T14:30:00",
"end_time": "2025-10-21T14:35:30",
"pages_scraped": 42,
"total_visited": 45,
"errors": {
"https://example.com/broken": "HTTP 404",
"https://example.com/slow": "Timeout"
}
}
コンテンツの抽出とフィルタリング
抽出される内容
スクレイパーは、次の方法でクリーンなテキストコンテンツを抽出します。
-
メインコンテンツに注目する -
<main>、<article>、または<body>タグを優先します -
不要な要素を削除する - 次の要素を取り除きます。
- スクリプトとスタイル
- ナビゲーションメニュー
- ヘッダーとフッター
- サイドバー(asideタグ)
- iframeと埋め込みコンテンツ
- SVGグラフィック
- コメント
-
一般的なパターンをフィルタリングする - 次の項目を取り除きます。
- Cookie同意メッセージ
- プライバシーポリシーへのリンク
- 利用規約の定型文
- UI要素(矢印、単独の数字)
- 極端に短い行(ナビゲーション項目と思われるもの)
-
構造を維持する - コンテンツブロック間の改行を維持します
フィルタリングされる内容
自動的に削除される一般的な不要パターン:
- 「Accept cookies」/「Reject all」
- 「Cookie settings」
- 「Privacy policy」
- 「Terms of service」
- ナビゲーション矢印(←、→、↑、↓)
- 単独の数字
- 3文字未満の行
一般的な使用パターン
ドキュメントサイトをダウンロードする
適切な制限を設定して、ドキュメントサイト全体をスクレイピングします。
python scripts/scrape.py https://docs.example.com docs-archive/ --depth 3 --max-pages 200 --concurrent 15
ブログをアーカイブする
ページネーションをたどりながら、ブログの投稿をすべてダウンロードします。
python scripts/scrape.py https://blog.example.com blog-archive/ --depth 2 --max-pages 500
調査データを収集する
関連する複数のソースからテキストコンテンツを収集します。
python scripts/scrape.py https://research.edu/papers https://research.edu/publications research-data/ --depth 2 --allowed-domains research.edu --concurrent 20
大規模サイトのサンプルを取得する
サイト全体をスクレイピングする前に、小規模なサンプルで設定をテストします。
python scripts/scrape.py https://largeSite.com sample/ --depth 2 --max-pages 20 --verbose
結果を確認したら、サイト全体のスクレイピングを実行します。
python scripts/scrape.py https://largeSite.com full-archive/ --depth 3 --max-pages 500 --concurrent 15
複数ドメインのナレッジベース
許可された複数のドメインを対象にスクレイピングします。
python scripts/scrape.py https://main.example.com knowledge-base/ --depth 3 --allowed-domains main.example.com docs.example.com wiki.example.com --max-pages 300
実装方法
ユーザーがウェブスクレイピングを依頼した場合:
-
対象範囲を特定する:
- 開始するURLはどれですか?
- リンクをたどりますか?たどる場合、深さはいくつですか?
- ドメイン制限は必要ですか?
- 適切なページ数の上限はありますか?
-
スクレイパーを設定する:
- 適切な深さを設定します(通常は1~3)
- 無制限のスクレイピングを防ぐため、max-pagesを設定します
- サイトの規模に応じて同時実行数を選択します
- ドメイン制限を決定します
-
監視しながら実行する:
- まず詳細モードまたは小規模なサンプルで開始します
- エラーや予期しないコンテンツがないか、出力を監視します
- 必要に応じて設定を調整します
-
出力を確認する:
- 出力ディレクトリの構造を確認します
- 統計情報について
_metadata.jsonを確認します - いくつかのテキストファイルをサンプルとして品質を確認します
- メタデータにエラーがないか確認します
-
コンテンツを処理する:
- テキストファイルはコンテキストに読み込める状態です
- Readツールを使って特定のファイルを確認します
- Grepを使ってスクレイピングしたすべてのコンテンツを検索します
- 分析に必要なファイルを読み込みます
クイックリファレンス
コマンドの構成:
python scripts/scrape.py <URL> [URL2 ...] <output-dir> [options]
主なオプション:
-d, --depth N- リンクの最大深度(デフォルト:2)-m, --max-pages N- スクレイピングするページの最大数-c, --concurrent N- 同時リクエスト数(デフォルト:10)-f, --follow-external- 外部リンクをたどります-a, --allowed-domains- 許可するドメインを指定します-v, --verbose- 詳細な出力-u, --user-agent- カスタムUser-Agent-t, --timeout- リクエストのタイムアウト(秒)
ヘルプ全体を表示:
python scripts/scrape.py --help
ベストプラクティス
- 小さく始める - 大規模なスクレイピングの前に、
--depth 1 --max-pages 10でテストします - サーバーに配慮する - 適切な同時実行数とタイムアウトを使用します
- 上限を設定する - 初回の実行では必ず
--max-pagesを使用します - robots.txtを確認する - サイトがスクレイピングを許可しているか、手動で確認します
- 詳細モードを使用する - エラーや予期しない動作がないか監視します
- 身元を明らかにする - 連絡先情報を含む、説明的なUser-Agentを使用します
- 出力を監視する - エラーと統計情報について
_metadata.jsonを確認します - エラーに適切に対処する - 問題のあるURLについて、メタデータ内のエラーログを確認します
トラブルシューティング
よくある問題:
- 「必須の依存関係がありません」:
pip install aiohttp beautifulsoup4 lxml aiofilesを実行します - タイムアウトが多すぎる:
--timeoutを増やすか、--concurrentを減らします - スクレイピングが遅すぎる:
--concurrentを増やします(例:20~30) - 大規模なスクレイピングでメモリの問題が発生する:
--concurrentを減らすか、--max-pagesを使用して作業を分割します - リンクをたどりすぎる:
--depthを減らすか、同一ドメインのみの設定を有効にします(デフォルト) - コンテンツが見つからない:サイトによっては JavaScript が必要な場合があります。このスクレイパーは静的 HTML のみを処理します
- HTTP エラー:具体的な問題については、
_metadata.jsonのエラーセクションを確認します
制限事項:
- JavaScript を実行しません(シングルページアプリでは動作しない場合があります)
- 認証やログインには対応していません
- JavaScript 内のリンクや動的に読み込まれるコンテンツはたどりません
- レート制限機能は組み込まれていません(リクエスト頻度を制御するには
--concurrentを使用します)
高度な使用例
スクレイピングしたコンテンツの読み込み
スクレイピング後、Read ツールを使用してコンテンツをコンテキストに読み込みます:
# Read a specific scraped page
Read file_path: output/docs.example.com/guide.txt
# Search across all scraped content
Grep pattern: "API endpoint" path: output/ -r
選択的な再スクレイピング
スクレイパーはセッション中にメモリ上でアクセス済み URL を追跡しますが、実行間では保持しません。再ダウンロードを避けるには:
- 制限を設定して初回のスクレイピングを実行します
- 出力ディレクトリでダウンロードされた内容を確認します
- 開始 URL または設定を変えて追加のスクレイピングを実行します
他のツールとの組み合わせ
スクレイパーを他の処理と連鎖させます:
# Scrape then process with custom script
python scripts/scrape.py https://example.com output/ --depth 2
python your_analysis_script.py output/
リソース
scripts/scrape.py
同時クロール、コンテンツ抽出、インテリジェントなフィルタリングを実装する、主要なウェブスクレイピングツールです。主な機能:
- 非同期/同時処理 -
asyncioとaiohttpを使用して、高速な同時リクエストを実行します - URL の正規化 - 適切に重複を排除できるよう、フラグメントと末尾のスラッシュを削除します
- アクセス済み URL の追跡 - 再ダウンロードを防ぐため、
visited_urlsとqueued_urlsのセットを保持します - スマートなコンテンツ抽出 - スクリプト、スタイル、ナビゲーション、一般的な不要パターンを削除します
- ディレクトリ階層 - URL を、安全なファイルシステムパスに変換して構造を維持します
- エラー処理 - メタデータファイルでエラーを追跡して報告します
- メタデータ生成 - スクレイピングの統計情報とエラーを含む
_metadata.jsonを作成します
スクリプトは直接実行でき、--help で包括的なコマンドラインヘルプを確認できます。