Panduan Pertengahan
Panduan Pemprosesan Kelompok
Skalakan scraping web ke beribu-ribu URL dengan pengurusan baris gilir yang cekap, pemulihan ralat, dan strategi 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/BusinessGunakan 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
| Senario | Masa | Tetapan |
|---|---|---|
| Kelompok Kecil (10 URL) | ~5 saat | maxConcurrency: 5 |
| Kelompok Sederhana (50 URL) | ~15 saat | maxConcurrency: 10 |
| Kelompok Besar (500 URL) | ~3 minit | 10 kelompok × 50 URL |
| Kelompok Sangat Besar (5,000 URL) | ~30 minit | 100 kelompok × 50 URL |
Langkah Seterusnya
Teruskan pembelajaran dengan lebih banyak panduan lanjutan