jpskill.com
🛠️ 開発・MCP コミュニティ

crawlee

ウェブサイトから大量のデータを効率的に収集したい場合に、JavaScriptで動的に生成されるページにも対応し、プロキシ設定やデータ出力機能も備えた、信頼性の高いスクレイピングやクローラーを構築するSkill。

📜 元の英語説明(参考)

Build reliable web scrapers and crawlers with Crawlee — Apify's open-source framework for structured web scraping. Use when someone asks to "scrape a website", "build a crawler", "Crawlee", "web scraping at scale", "scrape JavaScript-rendered pages", "crawl with Playwright/Puppeteer", or "extract data from websites reliably". Covers HTTP crawling, browser crawling, request queues, proxy rotation, and data export.

🇯🇵 日本人クリエイター向け解説

一言でいうと

ウェブサイトから大量のデータを効率的に収集したい場合に、JavaScriptで動的に生成されるページにも対応し、プロキシ設定やデータ出力機能も備えた、信頼性の高いスクレイピングやクローラーを構築するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o crawlee.zip https://jpskill.com/download/14797.zip && unzip -o crawlee.zip && rm crawlee.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14797.zip -OutFile "$d\crawlee.zip"; Expand-Archive "$d\crawlee.zip" -DestinationPath $d -Force; ri "$d\crawlee.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して crawlee.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → crawlee フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Crawlee

概要

Crawlee は、リクエストのキューイング、リトライ、プロキシのローテーション、ブラウザのフィンガープリント、レート制限といった面倒な部分を処理するウェブスクレイピングおよびクローリングライブラリです。高速な HTML のみのスクレイピングには Cheerio を、JavaScript でレンダリングされたページには Playwright/Puppeteer を使用します。データセット、リクエストキュー、キーバリューストアのための組み込みストレージがあります。単一のページから数百万の URL までスケール可能です。

どのような時に使うか

  • ウェブサイトからのデータスクレイピング(製品価格、求人情報、記事)
  • コンテンツまたはリンク分析のためのサイト全体のクローリング
  • JavaScript でレンダリングされたページ(SPA、React/Vue サイト)
  • プロキシのローテーションとアンチブロッキングによる大規模なスクレイピング
  • 自動リトライによる構造化データ抽出

手順

セットアップ

npm install crawlee playwright
npx playwright install chromium  # ブラウザクローリングの場合のみ

HTTP クローリング(高速、ブラウザ不要)

// scraper.ts — Cheerio を使用した高速スクレイピング(ブラウザ不要)
import { CheerioCrawler, Dataset } from "crawlee";

const crawler = new CheerioCrawler({
  maxConcurrency: 10,          // 並列リクエスト数
  maxRequestRetries: 3,        // 失敗したリクエストのリトライ回数
  requestHandlerTimeoutSecs: 30,

  async requestHandler({ request, $, enqueueLinks, pushData }) {
    // $ は Cheerio — jQuery のようなセレクター API
    const title = $("h1").text().trim();
    const price = $("[data-testid='price']").text().trim();
    const description = $("meta[name='description']").attr("content");

    // 構造化データを保存
    await pushData({
      url: request.url,
      title,
      price,
      description,
      scrapedAt: new Date().toISOString(),
    });

    // ページネーションリンクをたどる
    await enqueueLinks({
      selector: "a.next-page",
      label: "LISTING",
    });
  },

  // 異なるページタイプを処理
  async failedRequestHandler({ request }) {
    console.error(`Failed: ${request.url} after ${request.retryCount} retries`);
  },
});

// クローリングを開始
await crawler.run(["https://example-shop.com/products"]);

// データのエクスポート
const dataset = await Dataset.open();
await dataset.exportToCSV("products");

ブラウザクローリング(JavaScript でレンダリングされたページ)

// browser-scraper.ts — Playwright で JS レンダリングされたページをスクレイピング
import { PlaywrightCrawler } from "crawlee";

const crawler = new PlaywrightCrawler({
  maxConcurrency: 5,           // 並行処理数を少なく — ブラウザは重い
  headless: true,
  launchContext: {
    launchOptions: {
      args: ["--disable-blink-features=AutomationControlled"],
    },
  },

  async requestHandler({ page, request, pushData, enqueueLinks }) {
    // 動的なコンテンツがロードされるのを待つ
    await page.waitForSelector("[data-loaded='true']", { timeout: 10000 });

    // Playwright セレクターを使用してデータを抽出
    const items = await page.$$eval(".product-card", (cards) =>
      cards.map((card) => ({
        name: card.querySelector("h3")?.textContent?.trim(),
        price: card.querySelector(".price")?.textContent?.trim(),
        rating: card.querySelector(".stars")?.getAttribute("data-rating"),
      }))
    );

    for (const item of items) {
      await pushData({ ...item, sourceUrl: request.url });
    }

    // スクロールしてさらにロード(無限スクロール)
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(2000);

    // "Load More" が存在する場合はクリック
    const loadMore = page.locator("button:has-text('Load More')");
    if (await loadMore.isVisible()) {
      await loadMore.click();
      await page.waitForLoadState("networkidle");
    }
  },
});

await crawler.run(["https://spa-example.com/products"]);

プロキシのローテーション

// proxy-scraper.ts — ブロッキングを避けるためにプロキシをローテーション
import { CheerioCrawler, ProxyConfiguration } from "crawlee";

const proxyConfig = new ProxyConfiguration({
  proxyUrls: [
    "http://user:pass@proxy1.example.com:8080",
    "http://user:pass@proxy2.example.com:8080",
    "http://user:pass@proxy3.example.com:8080",
  ],
});

const crawler = new CheerioCrawler({
  proxyConfiguration: proxyConfig,
  // Crawlee は自動的にプロキシをローテーションし、失敗したプロキシをリトライします
  async requestHandler({ request, $, pushData, proxyInfo }) {
    console.log(`Using proxy: ${proxyInfo?.url}`);
    // ... スクレイピングロジック
  },
});

例 1: e コマースサイトから製品データをスクレイピングする

ユーザープロンプト: "example-shop.com からすべての製品名、価格、評価をスクレイピングし、CSV にエクスポートしてください。"

エージェントは、ページネーション処理、構造化データ抽出、および CSV エクスポートを備えた CheerioCrawler を作成します。

例 2: 競合他社の価格を監視する

ユーザープロンプト: "競合他社の価格をチェックし、変更があった場合にアラートを送信する毎日のスクレイパーを構築してください。"

エージェントは、JS でレンダリングされたページ用の PlaywrightCrawler を作成し、価格をデータセットに保存し、以前の実行と比較し、変更があった場合にアラートを送信します。

ガイドライン

  • 静的な HTML には Cheerio — ブラウザクローリングより 10 倍高速
  • SPA には Playwright — JavaScript レンダリングが必要な場合にのみ使用
  • クローリングには enqueueLinks — 自動的にリンクをたどり、重複排除
  • 構造化された出力には pushData — CSV/JSON にエクスポートするデータセットを構築
  • スケールにはプロキシのローテーション — Crawlee は失敗したプロキシを自動的にリトライ
  • robots.txt を尊重 — クローラー設定で robotsTxtUrl を確認
  • レート制限 — ターゲットに過負荷をかけないように maxRequestsPerMinute を設定
  • リクエストラベル — ラベルを使用して、異なるページタイプを異なるハンドラーにルーティング
  • エラー処理failedRequestHandler は失敗した URL をキャッチしてログに記録
  • ストレージは永続化 — データセットとキューはデフォルトで再起動後も保持
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Crawlee

Overview

Crawlee is a web scraping and crawling library that handles the hard parts — request queuing, retries, proxy rotation, browser fingerprinting, and rate limiting. Use Cheerio for fast HTML-only scraping or Playwright/Puppeteer for JavaScript-rendered pages. Built-in storage for datasets, request queues, and key-value stores. Scales from single pages to millions of URLs.

When to Use

  • Scraping data from websites (product prices, job listings, articles)
  • Crawling entire sites for content or link analysis
  • JavaScript-rendered pages (SPAs, React/Vue sites)
  • Scraping at scale with proxy rotation and anti-blocking
  • Structured data extraction with automatic retries

Instructions

Setup

npm install crawlee playwright
npx playwright install chromium  # Only for browser crawling

HTTP Crawling (Fast, No Browser)

// scraper.ts — Fast scraping with Cheerio (no browser needed)
import { CheerioCrawler, Dataset } from "crawlee";

const crawler = new CheerioCrawler({
  maxConcurrency: 10,          // Parallel requests
  maxRequestRetries: 3,        // Retry failed requests
  requestHandlerTimeoutSecs: 30,

  async requestHandler({ request, $, enqueueLinks, pushData }) {
    // $ is Cheerio — jQuery-like selector API
    const title = $("h1").text().trim();
    const price = $("[data-testid='price']").text().trim();
    const description = $("meta[name='description']").attr("content");

    // Save structured data
    await pushData({
      url: request.url,
      title,
      price,
      description,
      scrapedAt: new Date().toISOString(),
    });

    // Follow pagination links
    await enqueueLinks({
      selector: "a.next-page",
      label: "LISTING",
    });
  },

  // Handle different page types
  async failedRequestHandler({ request }) {
    console.error(`Failed: ${request.url} after ${request.retryCount} retries`);
  },
});

// Start crawling
await crawler.run(["https://example-shop.com/products"]);

// Export data
const dataset = await Dataset.open();
await dataset.exportToCSV("products");

Browser Crawling (JavaScript-Rendered Pages)

// browser-scraper.ts — Scrape JS-rendered pages with Playwright
import { PlaywrightCrawler } from "crawlee";

const crawler = new PlaywrightCrawler({
  maxConcurrency: 5,           // Fewer concurrent — browsers are heavy
  headless: true,
  launchContext: {
    launchOptions: {
      args: ["--disable-blink-features=AutomationControlled"],
    },
  },

  async requestHandler({ page, request, pushData, enqueueLinks }) {
    // Wait for dynamic content to load
    await page.waitForSelector("[data-loaded='true']", { timeout: 10000 });

    // Extract data using Playwright selectors
    const items = await page.$$eval(".product-card", (cards) =>
      cards.map((card) => ({
        name: card.querySelector("h3")?.textContent?.trim(),
        price: card.querySelector(".price")?.textContent?.trim(),
        rating: card.querySelector(".stars")?.getAttribute("data-rating"),
      }))
    );

    for (const item of items) {
      await pushData({ ...item, sourceUrl: request.url });
    }

    // Scroll to load more (infinite scroll)
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(2000);

    // Click "Load More" if exists
    const loadMore = page.locator("button:has-text('Load More')");
    if (await loadMore.isVisible()) {
      await loadMore.click();
      await page.waitForLoadState("networkidle");
    }
  },
});

await crawler.run(["https://spa-example.com/products"]);

Proxy Rotation

// proxy-scraper.ts — Rotate proxies to avoid blocking
import { CheerioCrawler, ProxyConfiguration } from "crawlee";

const proxyConfig = new ProxyConfiguration({
  proxyUrls: [
    "http://user:pass@proxy1.example.com:8080",
    "http://user:pass@proxy2.example.com:8080",
    "http://user:pass@proxy3.example.com:8080",
  ],
});

const crawler = new CheerioCrawler({
  proxyConfiguration: proxyConfig,
  // Crawlee automatically rotates and retires failing proxies
  async requestHandler({ request, $, pushData, proxyInfo }) {
    console.log(`Using proxy: ${proxyInfo?.url}`);
    // ... scraping logic
  },
});

Examples

Example 1: Scrape product data from an e-commerce site

User prompt: "Scrape all product names, prices, and ratings from example-shop.com and export to CSV."

The agent will create a CheerioCrawler with pagination handling, structured data extraction, and CSV export.

Example 2: Monitor competitor prices

User prompt: "Build a daily scraper that checks competitor prices and alerts when they change."

The agent will create a PlaywrightCrawler for JS-rendered pages, store prices in a dataset, compare with previous runs, and send alerts on changes.

Guidelines

  • Cheerio for static HTML — 10x faster than browser crawling
  • Playwright for SPAs — use only when JavaScript rendering is required
  • enqueueLinks for crawling — automatically follows and deduplicates links
  • pushData for structured output — builds a dataset that exports to CSV/JSON
  • Proxy rotation for scale — Crawlee retires failing proxies automatically
  • Respect robots.txt — check robotsTxtUrl in crawler config
  • Rate limitmaxRequestsPerMinute to avoid overwhelming targets
  • Request labels — use labels to route different page types to different handlers
  • Error handlingfailedRequestHandler catches and logs failed URLs
  • Storage persists — datasets and queues survive restarts by default