CrawlForge
Panduan Pertengahan

Panduan Pemprosesan Kelompok

Skalakan scraping web ke beribu-ribu URL dengan pengurusan baris gilir yang cekap, pemulihan ralat, dan strategi pengoptimuman prestasi.

Menggunakan Alat batch_scrape
Pengurusan Baris Gilir
Pemulihan Ralat
Pengoptimuman Prestasi

1. Menggunakan Alat batch_scrape

Alat batch_scrape mengendalikan sehingga 50 URL secara serentak dengan pengehadan kadar terbina dalam dan pemberitahuan webhook.

Scraping Kelompok Asas

1 credit setiap URL (50 URL = 50 credits)

Bash
curl -X POST https://crawlforge.dev/api/v1/tools/batch_scrape \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://example.com/page1",
      "https://example.com/page2",
      "https://example.com/page3"
    ],
    "formats": ["markdown"],
    "maxConcurrency": 5,
    "onlyMainContent": true
  }'

Pemprosesan Async dengan Webhook

Sesuai untuk kelompok besar (100+ URL) - terima pemberitahuan apabila selesai

Typescript
// Start batch job with webhook
const response = await fetch('https://crawlforge.dev/api/v1/tools/batch_scrape', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.CRAWLFORGE_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    urls: largeUrlList, // 100+ URLs
    formats: ['markdown'],
    webhook: 'https://yourapp.com/webhook/batch-complete',
    maxConcurrency: 10
  }),
});

const { jobId } = await response.json();
console.log(`Batch job started: ${jobId}`);

// Webhook handler (Express.js example)
app.post('/webhook/batch-complete', (req, res) => {
  const { jobId, status, results, errors } = req.body;

  if (status === 'completed') {
    console.log(`Job ${jobId} completed!`);
    console.log(`Success: ${results.length} pages`);
    console.log(`Errors: ${errors.length} pages`);

    // Process results
    results.forEach(result => {
      saveToDatabase(result.url, result.content);
    });
  }

  res.sendStatus(200);
});

2. Pengurusan Baris Gilir

Proses beribu-ribu URL dengan memecahkannya kepada kelompok dan menguruskan baris gilir.

Strategi Pemecahan

Pecahkan senarai URL yang besar kepada kelompok yang boleh diuruskan

Typescript
// Chunk array into batches of 50
function chunkArray<T>(array: T[], size: number): T[][] {
  const chunks: T[][] = [];
  for (let i = 0; i < array.length; i += size) {
    chunks.push(array.slice(i, i + size));
  }
  return chunks;
}

// Process all URLs in batches
async function processBatches(urls: string[]) {
  const batches = chunkArray(urls, 50); // Max 50 URLs per batch
  const allResults: any[] = [];

  for (let i = 0; i < batches.length; i++) {
    const batch = batches[i];
    console.log(`Processing batch ${i + 1}/${batches.length}...`);

    const response = await fetch('https://crawlforge.dev/api/v1/tools/batch_scrape', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.CRAWLFORGE_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        urls: batch,
        formats: ['markdown'],
        maxConcurrency: 10
      }),
    });

    const data = await response.json();
    allResults.push(...data.data.results);

    // Wait between batches to respect rate limits
    if (i < batches.length - 1) {
      await new Promise(resolve => setTimeout(resolve, 2000));
    }
  }

  return allResults;
}

// Usage
const urls = [...]; // 500 URLs
const results = await processBatches(urls);
console.log(`Scraped ${results.length} total pages`);
Petua Pro: Gunakan Redis atau pangkalan data untuk menyimpan baris gilir anda. Ini membolehkan anda menyambung semula pemprosesan jika skrip anda terhempas atau perlu dimulakan semula.

3. Pemulihan Ralat

Kendalikan kegagalan dengan baik menggunakan logik cuba semula dan penjejakan ralat.

Pengendalian Ralat yang Mantap

Typescript
interface BatchResult {
  successful: any[];
  failed: { url: string; error: string }[];
}

async function batchScrapeWithRetry(
  urls: string[],
  maxRetries = 3
): Promise<BatchResult> {
  const successful: any[] = [];
  const failed: { url: string; error: string }[] = [];
  let remainingUrls = [...urls];
  let retries = 0;

  while (remainingUrls.length > 0 && retries <= maxRetries) {
    try {
      const response = await fetch('https://crawlforge.dev/api/v1/tools/batch_scrape', {
        method: 'POST',
        headers: {
          'X-API-Key': process.env.CRAWLFORGE_API_KEY!,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          urls: remainingUrls,
          formats: ['markdown'],
          maxConcurrency: 5
        }),
      });

      const data = await response.json();

      // Separate successful and failed results
      const batchSuccessful = data.data.results.filter((r: any) => r.success);
      const batchFailed = data.data.results.filter((r: any) => !r.success);

      successful.push(...batchSuccessful);

      // Only retry failed URLs
      remainingUrls = batchFailed.map((r: any) => r.url);

      if (remainingUrls.length > 0) {
        console.log(`Retrying ${remainingUrls.length} failed URLs...`);
        retries++;
        await new Promise(resolve => setTimeout(resolve, 2000 * retries));
      }

    } catch (error) {
      console.error('Batch request failed:', error);
      retries++;

      if (retries > maxRetries) {
        // Mark all remaining URLs as failed
        failed.push(...remainingUrls.map(url => ({
          url,
          error: String(error)
        })));
        break;
      }

      await new Promise(resolve => setTimeout(resolve, 2000 * retries));
    }
  }

  return { successful, failed };
}

// Usage
const { successful, failed } = await batchScrapeWithRetry(urls);
console.log(`Success: ${successful.length}, Failed: ${failed.length}`);

// Save failed URLs for manual review
if (failed.length > 0) {
  fs.writeFileSync('failed-urls.json', JSON.stringify(failed, null, 2));
}

4. Pengoptimuman Prestasi

Maksimumkan throughput dan minimumkan kos dengan strategi pengoptimuman ini.

Optimumkan Keserentakan
Mulakan dengan maxConcurrency: 5, tingkatkan kepada 10 untuk pelan Professional/Business
Gunakan onlyMainContent
Tetapkan onlyMainContent: true untuk mengurangkan saiz respons sebanyak 60-80%
Pilih Format Minimum
Gunakan formats: ["markdown"] dan bukannya berbilang format (html, text, screenshot)
Cache Keputusan
Simpan data yang di-scrape dalam Redis/pangkalan data untuk mengelakkan scraping semula URL yang sama
Elakkan Pengelompokan Berlebihan
Jangan melebihi 50 URL setiap kelompok - pecahkan kepada berbilang permintaan sebaliknya
Jangan Abaikan Had Kadar
Hormati had kadar pelan anda (Free: 5/s, Hobby: 10/s, Pro: 50/s, Business: 100/s)

Prestasi Dijangka

SenarioMasaTetapan
Kelompok Kecil (10 URL)~5 saatmaxConcurrency: 5
Kelompok Sederhana (50 URL)~15 saatmaxConcurrency: 10
Kelompok Besar (500 URL)~3 minit10 kelompok × 50 URL
Kelompok Sangat Besar (5,000 URL)~30 minit100 kelompok × 50 URL
Langkah Seterusnya
Teruskan pembelajaran dengan lebih banyak panduan lanjutan
Pengoptimuman Credit →
Minimumkan kos
Teknik Stealth →
Pintas sistem anti-bot