mcpField
W
web-scraper

web-scraper

github.com/igosukiデータ・データベース157 回インストール53 週間前に更新
リポジトリ

web-scraper について

Web Scraperは、ウェブサイトをクロールし、抽出したテキストをローカルに保存するコマンドラインスキルおよびスクリプトです。ページ数やドメインを制限した再帰・並行取得とノイズ除去に対応し、静的HTMLのみを扱います。

主な機能

  1. 01リンクをたどる再帰クロール
  2. 02HTTPリクエストの並行処理
  3. 03ページ数とドメインの制限
  4. 04本文テキストの抽出とフィルタリング
  5. 05URL構造に沿った出力ディレクトリ
  6. 06セッション情報とエラーログの記録

活用シーン

  1. 01ドキュメントサイトのアーカイブ
  2. 02関連ドメインからのテキスト収集
  3. 03ページ数を制限した大規模サイトのサンプル取得
  4. 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"
  }
}

コンテンツの抽出とフィルタリング

抽出される内容

スクレイパーは、次の方法でクリーンなテキストコンテンツを抽出します。

  1. メインコンテンツに注目する - <main>、<article>、または<body>タグを優先します

  2. 不要な要素を削除する - 次の要素を取り除きます。

    • スクリプトとスタイル
    • ナビゲーションメニュー
    • ヘッダーとフッター
    • サイドバー(asideタグ)
    • iframeと埋め込みコンテンツ
    • SVGグラフィック
    • コメント
  3. 一般的なパターンをフィルタリングする - 次の項目を取り除きます。

    • Cookie同意メッセージ
    • プライバシーポリシーへのリンク
    • 利用規約の定型文
    • UI要素(矢印、単独の数字)
    • 極端に短い行(ナビゲーション項目と思われるもの)
  4. 構造を維持する - コンテンツブロック間の改行を維持します

フィルタリングされる内容

自動的に削除される一般的な不要パターン:

  • 「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

実装方法

ユーザーがウェブスクレイピングを依頼した場合:

  1. 対象範囲を特定する:

    • 開始するURLはどれですか?
    • リンクをたどりますか?たどる場合、深さはいくつですか?
    • ドメイン制限は必要ですか?
    • 適切なページ数の上限はありますか?
  2. スクレイパーを設定する:

    • 適切な深さを設定します(通常は1~3)
    • 無制限のスクレイピングを防ぐため、max-pagesを設定します
    • サイトの規模に応じて同時実行数を選択します
    • ドメイン制限を決定します
  3. 監視しながら実行する:

    • まず詳細モードまたは小規模なサンプルで開始します
    • エラーや予期しないコンテンツがないか、出力を監視します
    • 必要に応じて設定を調整します
  4. 出力を確認する:

    • 出力ディレクトリの構造を確認します
    • 統計情報について_metadata.jsonを確認します
    • いくつかのテキストファイルをサンプルとして品質を確認します
    • メタデータにエラーがないか確認します
  5. コンテンツを処理する:

    • テキストファイルはコンテキストに読み込める状態です
    • 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

ベストプラクティス

  1. 小さく始める - 大規模なスクレイピングの前に、--depth 1 --max-pages 10でテストします
  2. サーバーに配慮する - 適切な同時実行数とタイムアウトを使用します
  3. 上限を設定する - 初回の実行では必ず--max-pagesを使用します
  4. robots.txtを確認する - サイトがスクレイピングを許可しているか、手動で確認します
  5. 詳細モードを使用する - エラーや予期しない動作がないか監視します
  6. 身元を明らかにする - 連絡先情報を含む、説明的なUser-Agentを使用します
  7. 出力を監視する - エラーと統計情報について_metadata.jsonを確認します
  8. エラーに適切に対処する - 問題のある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 を追跡しますが、実行間では保持しません。再ダウンロードを避けるには:

  1. 制限を設定して初回のスクレイピングを実行します
  2. 出力ディレクトリでダウンロードされた内容を確認します
  3. 開始 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 で包括的なコマンドラインヘルプを確認できます。

コメント