Web Scraping in Cursor: Ein vollständiger Leitfaden

Web Scraping ist der Prozess des programmatischen Extrahierens von Daten von Websites. Es ermöglicht Preisüberwachung, Lead-Generierung, Nachrichtenaggregation, Marktforschung und Datensammlung für maschinelles Lernen. Das Node.js-Ökosystem bietet drei dominante Tools: Puppeteer für Headless-Chrome-Automatisierung, Playwright für browserübergreifende Automatisierung und Cheerio für schnelles HTML-Parsing. Cursor ist mit seinem integrierten KI-Assistenten und dem eingebauten TypeScript-Language-Server ein hervorragender Editor für Scraping-Projekte -- er bietet IntelliSense für Browser-APIs, auto-vervollständigt Selektor-Ketten und kann Extraktionslogik aus natürlichsprachlichen Beschreibungen von Webseiten generieren.
Dieser Leitfaden behandelt den vollständigen Web-Scraping-Workflow in Cursor: Wahl des richtigen Tools, Einrichtung von Puppeteer und Playwright, HTML-Parsing mit Cheerio, Implementierung von Extraktionsmustern, Umgehung von Anti-Bot-Maßnahmen und Nutzung der KI-gestützten Extraktion.
Wahl des richtigen Tools
Jedes Scraping-Tool hat unterschiedliche Stärken. Zu verstehen, wann man welches einsetzt, ist die Grundlage einer effektiven Scraping-Strategie.
| Tool | Am besten für | Browser | Geschwindigkeit | Komplexität |
|---|---|---|---|---|
| Cheerio | Statisches HTML, schnelles Parsing | Keiner | Sehr schnell | Niedrig |
| Puppeteer | Dynamische JS-gerenderte Seiten | Chrome/Chromium | Mittel | Mittel |
| Playwright | Browserübergreifend, moderne SPAs | Chrome, Firefox, WebKit | Mittel | Mittel-Hoch |
| Puppeteer + Cheerio | Hybrid-Ansatz | Chrome | Schnell | Mittel |
Fragen Sie Cursor: "Ich muss eine Website scrapen. Die Daten, die ich benötige, werden nach dem Laden der Seite durch JavaScript gerendert. Welches Tool sollte ich verwenden und warum?" Cursor wird Puppeteer oder Playwright empfehlen und erklären, warum Cheerio allein dynamisch gerenderte Inhalte nicht erfassen kann.
Einrichten eines Scraping-Projekts in Cursor
Projektinitialisierung
mkdir web-scraper && cd web-scraper
npm init -y
npm install typescript tsx @types/node --save-dev
npx tsc --init
Verwenden Sie tsx, um TypeScript-Scraping-Skripte direkt ohne separaten Build-Schritt auszuführen. Führen Sie npx tsx scraper.ts im integrierten Terminal von Cursor (Ctrl+`) aus, um Skripte sofort zu testen.
Puppeteer installieren
npm install puppeteer
Puppeteer lädt standardmäßig ein gebündeltes Chromium herunter. Überprüfen Sie die Installation:
// test-puppeteer.ts
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
Playwright installieren
npm install playwright
npx playwright install # Lädt Browser-Binärdateien herunter
Überprüfen:
// test-playwright.ts
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
Cheerio installieren
npm install cheerio
Cheerio parst HTML-Zeichenfolgen ohne Browser und ist damit die schnellste Option für statische Seiten:
// test-cheerio.ts
import * as cheerio from 'cheerio';
const html = '<div class="item"><h2>Title</h2><span class="price">$9.99</span></div>';
const $ = cheerio.load(html);
console.log($('.item h2').text()); // "Title"
console.log($('.item .price').text()); // "$9.99"
Cheerio kann kein JavaScript ausführen. Wenn die Zielseite Inhalte dynamisch über clientseitiges JS rendert (React, Vue usw.), sieht Cheerio nur das anfängliche HTML-Gerüst. Verwenden Sie für diese Seiten Puppeteer oder Playwright.
Scraping mit Puppeteer
Puppeteer bietet eine High-Level-API zur Steuerung von Chrome oder Chromium. Es ist ideal zum Scrapen von JavaScript-gerenderten Seiten, zur Behandlung von Logins und zur Interaktion mit Seitenelementen.
Einfaches Seiten-Scraping
// scrape-products-puppeteer.ts
import puppeteer from 'puppeteer';
import * as cheerio from 'cheerio';
interface Product {
name: string;
price: string;
rating: string;
url: string;
}
async function scrapeProducts(): Promise<Product[]> {
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
try {
const page = await browser.newPage();
// Realistischen Viewport festlegen
await page.setViewport({ width: 1920, height: 1080 });
// Realistischen User-Agent festlegen
await page.setUserAgent(
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'
);
// Navigieren und auf das Rendern des Produkt-Rasters warten
await page.goto('https://example-store.com/products', {
waitUntil: 'networkidle2',
timeout: 30000,
});
// Auf das Erscheinen der Produktkarten warten
await page.waitForSelector('.product-card', { timeout: 10000 });
// Scrollen, um Lazy-Load-Inhalte auszulösen
await autoScroll(page);
// Daten von der Seite extrahieren
const products = await page.evaluate(() =>
Array.from(document.querySelectorAll('.product-card')).map((card) => ({
name: card.querySelector('.product-name')?.textContent?.trim() ?? '',
price: card.querySelector('.product-price')?.textContent?.trim() ?? '',
rating: card.querySelector('.product-rating')?.textContent?.trim() ?? '',
url: card.querySelector('a')?.href ?? '',
}))
);
return products;
} finally {
await browser.close();
}
}
async function autoScroll(page: puppeteer.Page) {
await page.evaluate(async () => {
await new Promise<void>((resolve) => {
let totalHeight = 0;
const distance = 100;
const timer = setInterval(() => {
window.scrollBy(0, distance);
totalHeight += distance;
if (totalHeight >= document.body.scrollHeight) {
clearInterval(timer);
resolve();
}
}, 100);
});
});
}
const products = await scrapeProducts();
console.log(`Scraped ${products.length} products`);
console.log(products[0]);
Die autoScroll-Funktion ist unerlässlich für Infinite-Scroll-Seiten. Viele Seiten laden Produkte verzögert beim Scrollen. Ohne Scrollen erfasst Puppeteer nur die anfangs geladenen Elemente.
Paginierung behandeln
async function scrapeAllPages(baseUrl: string): Promise<Product[]> {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
const allProducts: Product[] = [];
let currentPage = 1;
let hasNextPage = true;
try {
while (hasNextPage) {
await page.goto(`${baseUrl}?page=${currentPage}`, { waitUntil: 'networkidle2' });
await page.waitForSelector('.product-card', { timeout: 10000 });
const products = await page.evaluate(() =>
Array.from(document.querySelectorAll('.product-card')).map((card) => ({
name: card.querySelector('.product-name')?.textContent?.trim() ?? '',
price: card.querySelector('.product-price')?.textContent?.trim() ?? '',
rating: card.querySelector('.product-rating')?.textContent?.trim() ?? '',
url: card.querySelector('a')?.href ?? '',
}))
);
allProducts.push(...products);
hasNextPage = await page.evaluate(
() => document.querySelector('.pagination .next:not(.disabled)') !== null
);
currentPage++;
await new Promise((r) => setTimeout(r, 2000));
}
} finally {
await browser.close();
}
return allProducts;
}
Fügen Sie immer Verzögerungen zwischen Seitenanfragen hinzu. Zu schnelles Scrapen kann Rate-Limiting, IP-Sperren oder CAPTCHA-Herausforderungen auslösen. Eine Verzögerung von 1-3 Sekunden zwischen Anfragen ist ein guter Startpunkt. Für größere Crawls verwenden Sie einen Proxy-Rotationsdienst.
Login-geschützte Seiten behandeln
async function scrapeLoggedInPage(email: string, password: string) {
const browser = await puppeteer.launch({ headless: false }); // Browser für Debugging anzeigen
const page = await browser.newPage();
try {
await page.goto('https://example.com/login', { waitUntil: 'networkidle2' });
await page.type('#email', email, { delay: 50 });
await page.type('#password', password, { delay: 50 });
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle2' }),
page.click('#submit'),
]);
// Login-Erfolg verifizieren
const isLoggedIn = await page.evaluate(() => !document.querySelector('.login-error'));
if (!isLoggedIn) throw new Error('Login failed');
// Geschützte Seite scrapen
await page.goto('https://example.com/dashboard', { waitUntil: 'networkidle2' });
return await page.evaluate(() => document.querySelector('.dashboard-data')?.textContent);
} finally {
await browser.close();
}
}
Scraping mit Playwright
Playwright ist Microsofts browserübergreifendes Automatisierungs-Tool. Es unterstützt Chromium, Firefox und WebKit und hat eine modernere API als Puppeteer.
Einfaches Playwright-Scraping
// scrape-playwright.ts
import { chromium } from 'playwright';
interface Article {
title: string;
author: string;
date: string;
summary: string;
url: string;
}
async function scrapeArticles(): Promise<Article[]> {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
viewport: { width: 1920, height: 1080 },
});
const page = await context.newPage();
try {
await page.goto('https://example-blog.com', {
waitUntil: 'domcontentloaded',
timeout: 30000,
});
// Auf das Laden von Artikeln warten
await page.waitForSelector('.article-card', { timeout: 10000 });
const articles = await page.$$eval('.article-card', (cards) =>
cards.map((card) => ({
title: card.querySelector('.article-title')?.textContent?.trim() ?? '',
author: card.querySelector('.article-author')?.textContent?.trim() ?? '',
date: card.querySelector('.article-date')?.textContent?.trim() ?? '',
summary: card.querySelector('.article-summary')?.textContent?.trim() ?? '',
url: card.querySelector('a')?.href ?? '',
}))
);
return articles;
} finally {
await browser.close();
}
}
Scraping von SPAs mit Netzwerk-Interception
Playwright kann Netzwerkanfragen abfangen, um API-Antworten direkt zu erfassen, wodurch das Parsen von gerendertem HTML entfällt:
async function scrapeViaAPI() {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext();
const page = await context.newPage();
const apiResponses: any[] = [];
// API-Antworten abfangen
page.on('response', async (response) => {
if (response.url().includes('/api/products') && response.status() === 200) {
const json = await response.json();
apiResponses.push(json);
}
});
await page.goto('https://example-store.com', { waitUntil: 'networkidle' });
await browser.close();
// Jetzt haben Sie die rohen JSON-Daten, kein HTML-Parsing nötig
return apiResponses;
}
Netzwerk-Interception ist die zuverlässigste Methode zum Scrapen moderner SPAs. Anstatt gerendertes HTML zu parsen, erfassen Sie die JSON-API-Antworten, die die Seite abruft. Fragen Sie Cursor: "Fangen Sie die XHR-Anfragen auf dieser Seite ab und extrahieren Sie die Produktdaten aus der API-Antwort." Cursor wird den Playwright-Response-Listener generieren.
HTML-Parsing mit Cheerio
Cheerio bietet eine jQuery-ähnliche API zum Parsen von HTML-Zeichenfolgen. Es ist 10-100x schneller als browserbasiertes Scraping, da es keine Seiten rendert oder JavaScript ausführt.
Abrufen und Parsen
// scrape-cheerio.ts
import * as cheerio from 'cheerio';
interface Book {
title: string;
price: number;
availability: string;
rating: number;
}
async function scrapeBooks(): Promise<Book[]> {
const response = await fetch('https://books.toscrape.com/', {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
},
});
const html = await response.text();
const $ = cheerio.load(html);
const books: Book[] = [];
$('.product_pod').each((_, element) => {
const $el = $(element);
const title = $el.find('h3 a').attr('title') ?? '';
const priceText = $el.find('.price_color').text();
const price = parseFloat(priceText.replace(/[^0-9.]/g, ''));
const availability = $el.find('.instock').text().trim();
// Bewertung aus Klassennamen parsen (z.B. "star-rating Three" -> 3)
const ratingClass = $el.find('.star-rating').attr('class') ?? '';
const ratingMap: Record<string, number> = {
One: 1, Two: 2, Three: 3, Four: 4, Five: 5,
};
const ratingWord = ratingClass.split(' ')[1];
const rating = ratingMap[ratingWord] ?? 0;
books.push({ title, price, availability, rating });
});
return books;
}
Cheerio-Selektor-Muster
Cheerio verwendet jQuery-ähnliche Selektoren: $('.class') für Klassen, $('#id') für IDs, $('a[href*="/product/"]') für Attribut-Matching und Methoden wie .parent(), .siblings(), .children(), .text(), .html() und .attr() für DOM-Traversierung und Extraktion.
Wenn Sie jQuery-Selektoren kennen, kennen Sie Cheerio. Fragen Sie Cursor: "Schreiben Sie eine Cheerio-Selektor-Kette, um alle Produktnamen, Preise und Bild-URLs aus dieser HTML-Struktur zu extrahieren" und fügen Sie das HTML ein. Cursor wird die korrekten Selektoren generieren.
Datenextraktionsmuster
Strukturierte Daten aus Tabellen extrahieren
async function scrapeTable(): Promise<Record<string, string>[]> {
const response = await fetch('https://example.com/data-table');
const html = await response.text();
const $ = cheerio.load(html);
// Kopfzeilen abrufen
const headers: string[] = [];
$('table thead th').each((_, el) => {
headers.push($(el).text().trim().toLowerCase().replace(/\s+/g, '_'));
});
// Zeilen extrahieren
const rows: Record<string, string>[] = [];
$('table tbody tr').each((_, rowEl) => {
const cells: string[] = [];
$(rowEl).find('td').each((_, cellEl) => {
cells.push($(cellEl).text().trim());
});
const row: Record<string, string> = {};
headers.forEach((header, index) => {
row[header] = cells[index] ?? '';
});
rows.push(row);
});
return rows;
}
JSON-LD-Daten extrahieren
Viele Websites betten strukturierte Daten im JSON-LD-Format ein. Dies ist die zuverlässigste Extraktionsmethode, wenn verfügbar:
import * as cheerio from 'cheerio';
async function scrapeJsonLd(url: string) {
const response = await fetch(url);
const html = await response.text();
const $ = cheerio.load(html);
const jsonLdData: any[] = [];
$('script[type="application/ld+json"]').each((_, el) => {
try {
const data = JSON.parse($(el).contents().text());
if (Array.isArray(data)) {
jsonLdData.push(...data);
} else {
jsonLdData.push(data);
}
} catch (e) {
console.warn('Failed to parse JSON-LD:', e);
}
});
return jsonLdData;
}
// Verwendung
const structuredData = await scrapeJsonLd('https://example.com/product/123');
// structuredData[0] könnte enthalten: { "@type": "Product", "name": "...", "offers": { "price": "..." } }
JSON-LD ist der einfachste und zuverlässigste Weg, um strukturierte Daten zu extrahieren. Fragen Sie Cursor: "Prüfen Sie, ob diese Seite JSON-LD-strukturierte Daten hat, und extrahieren Sie die Produktinformationen daraus." Wenn die Website schema.org-Markup verwendet, wird Cursor es ohne fragwürdige CSS-Selektoren parsen.
Extrahierte Daten speichern
import { writeFileSync } from 'fs';
// Als JSON speichern
function saveToJson(data: any[], filename: string) {
writeFileSync(filename, JSON.stringify(data, null, 2));
console.log(`Saved ${data.length} records to ${filename}`);
}
// Als CSV speichern
function saveToCsv(data: Record<string, any>[], filename: string) {
if (data.length === 0) return;
const headers = Object.keys(data[0]);
const csvLines = [
headers.join(','),
...data.map((row) =>
headers.map((h) => `"${String(row[h] ?? '').replace(/"/g, '""')}"`).join(',')
),
];
writeFileSync(filename, csvLines.join('\n'));
}
Anti-Bot-Umgehungstechniken
Moderne Websites setzen Anti-Bot-Schutz (Cloudflare, reCAPTCHA, Datadome, PerimeterX) ein, um automatisiertes Scraping zu erkennen und zu blockieren. Hier sind Strategien zur Umgehung gängiger Schutzmechanismen.
Realistische Header setzen
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
};
const response = await fetch(url, { headers });
Puppeteer-Stealth verwenden
npm install puppeteer-extra puppeteer-extra-plugin-stealth
import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
// Das Stealth-Plugin patcht gängige Erkennungsvektoren:
// - navigator.webdriver = false
// - chrome.runtime object
// - permissions API
// - plugins array
// - languages array
// - WebGL vendor/renderer
await page.goto('https://bot-protected-site.com');
Stealth-Plugins helfen, sind aber kein Silberstreifen. Ausgereifte Anti-Bot-Dienste wie Cloudflare Turnstile nutzen TLS-Fingerprinting, Verhaltensanalyse und Challenge-Response-Mechanismen, die über einfache Navigator-Eigenschaftsprüfungen hinausgehen. Für Produktions-Scraping stark geschützter Seiten sollten Sie kommerzielle Proxy-Dienste mit integriertem CAPTCHA-Lösen in Betracht ziehen.
Proxies verwenden
// Puppeteer mit Proxy
const browser = await puppeteer.launch({
headless: true,
args: [
`--proxy-server=http://${proxyHost}:${proxyPort}`,
'--no-sandbox',
],
});
await page.authenticate({
username: proxyUsername,
password: proxyPassword,
});
// Playwright mit Proxy
const browser = await chromium.launch({
headless: true,
proxy: {
server: `http://${proxyHost}:${proxyPort}`,
username: proxyUsername,
password: proxyPassword,
},
});
User-Agents rotieren
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15',
];
const randomUA = userAgents[Math.floor(Math.random() * userAgents.length)];
await page.setUserAgent(randomUA);
Verzögerungen und menschenähnliches Verhalten
async function humanLikeScroll(page: puppeteer.Page) {
const totalHeight = await page.evaluate(() => document.body.scrollHeight);
let scrolled = 0;
while (scrolled < totalHeight) {
const scrollAmount = Math.floor(Math.random() * 200) + 100;
await page.evaluate((y) => window.scrollBy(0, y), scrollAmount);
scrolled += scrollAmount;
await new Promise((r) => setTimeout(r, Math.random() * 1500 + 500));
}
}
async function randomMouseMovement(page: puppeteer.Page) {
await page.mouse.move(Math.random() * 800, Math.random() * 600);
await new Promise((r) => setTimeout(r, Math.random() * 500 + 200));
await page.mouse.move(Math.random() * 800, Math.random() * 600);
}
Fragen Sie Cursor: "Lassen Sie meinen Puppeteer-Scraper sich menschenähnlicher verhalten. Fügen Sie zufällige Mausbewegungen, variable Scroll-Geschwindigkeiten und zufällige Verzögerungen zwischen Aktionen hinzu." Cursor wird die Verhaltens-Nachahmungsfunktionen generieren und in Ihren Scraping-Fluss integrieren.
KI-gestützte Extraktion in Cursor
Der KI-Assistent von Cursor kann Scraping-Logik aus Seitenbeschreibungen generieren, Selektoren aus HTML-Schnipseln identifizieren und fehlgeschlagene Extraktionen debuggen.
Selektoren aus HTML generieren
Öffnen Sie Cursor Chat (Ctrl+L) und fügen Sie einen HTML-Schnipsel ein:
Here is a product card's HTML structure:
<div class="product-item" data-id="123">
<img src="/img/product.jpg" alt="Product Name" />
<h3 class="product-title">Product Name</h3>
<span class="price-current">$29.99</span>
<span class="price-original">$49.99</span>
<span class="rating" data-rating="4.5">4.5 stars</span>
<span class="stock">In Stock</span>
</div>
Generate a Cheerio extraction function with a typed interface.
Include: productId, name, currentPrice, originalPrice, rating, stockStatus, imageUrl.
Cursor wird generieren:
interface ScrapedProduct {
productId: string;
name: string;
currentPrice: number;
originalPrice: number;
rating: number;
stockStatus: string;
imageUrl: string;
}
function extractProduct($: cheerio.CheerioAPI, element: any): ScrapedProduct {
const $el = $(element);
const parsePrice = (sel: string) =>
parseFloat($el.find(sel).text().replace(/[^0-9.]/g, '')) || 0;
return {
productId: $el.attr('data-id') ?? '',
name: $el.find('.product-title').text().trim(),
currentPrice: parsePrice('.price-current'),
originalPrice: parsePrice('.price-original'),
rating: parseFloat($el.find('.rating').attr('data-rating') ?? '0') || 0,
stockStatus: $el.find('.stock').text().trim(),
imageUrl: $el.find('img').attr('src') ?? '',
};
}
Wenn Sie Cursor bitten, Selektoren zu generieren, fügen Sie immer ein repräsentatives HTML-Beispiel ein. Dies stellt sicher, dass die Selektoren zur tatsächlichen DOM-Struktur passen und nicht auf einer Vermutung basieren. Cursor wird auch Randfälle wie fehlende optionale Felder identifizieren und Fallbacks hinzufügen.
KI-gestütztes Debugging
Wenn Ihr Scraper leere Ergebnisse zurückgibt, bitten Sie Cursor um Hilfe:
My Puppeteer scraper is returning an empty array. The selector
".product-card" should match elements but page.evaluate returns [].
Here is my code. The page loads successfully and I can see the elements
in the browser. What could be wrong?
Cursor wird häufige Probleme identifizieren:
- Der Selektor könnte sich in einem Shadow DOM befinden.
- Der Inhalt könnte in einem iframe sein.
- Die Seite könnte nach einem kürzlichen Redesign einen anderen Selektor verwenden.
- Die
waitUntil-Option könnte nicht ausreichen.
Websites ändern ihre HTML-Struktur häufig. Ein Scraper, der heute funktioniert, könnte morgen kaputt sein. Bauen Sie Ihre Scraper defensiv: verwenden Sie mehrere Fallback-Selektoren, protokollieren Sie Extraktionsfehler und richten Sie Monitoring ein, um zu erkennen, wenn Selektoren nicht mehr passen.
Best Practices und Ethik
robots.txt respektieren
async function checkRobotsTxt(url: string): Promise<boolean> {
const robotsUrl = `${new URL(url).origin}/robots.txt`;
try {
const robotsTxt = await (await fetch(robotsUrl)).text();
const path = new URL(url).pathname;
for (const line of robotsTxt.split('\n')) {
if (line.trim().toLowerCase().startsWith('disallow:')) {
const disallowed = line.split(':')[1].trim();
if (disallowed && path.startsWith(disallowed)) return false;
}
}
return true;
} catch {
return true; // Wenn robots.txt nicht existiert, erlaubt annehmen
}
}
Prüfen Sie immer robots.txt vor dem Scraping. Es ist das Standardprotokoll für Websites, um zu erklären, welche Seiten gescrapt werden dürfen. Verstoße gegen robots.txt können zu IP-Sperren und rechtlichen Problemen führen. Verwenden Sie die obenstehende checkRobotsTxt-Funktion vor jedem Scraping-Vorgang.
Rate Limiting
async function rateLimitedDelay() {
const delay = Math.random() * 2000 + 1000; // 1-3 Sekunden Verzögerung
await new Promise((r) => setTimeout(r, delay));
}
// Verwendung: zwischen jeder Seitenanfrage aufrufen
await rateLimitedDelay();
Fazit
Web Scraping in Cursor kombiniert die Macht von Puppeteer, Playwright und Cheerio mit KI-gestützter Code-Generierung. Cheerio ist Ihr Werkzeug für schnelles statisches HTML-Parsing, Puppeteer übernimmt JavaScript-gerenderte Seiten mit Chrome-Automatisierung und Playwright bietet browserübergreifende Unterstützung und Netzwerk-Interception für moderne SPAs. Anti-Bot-Techniken -- Stealth-Plugins, Proxy-Rotation und menschenähnliches Verhalten -- helfen Ihnen, geschützte Seiten zu erreichen, während der KI-Assistent von Cursor Selektoren aus HTML-Schnipseln generiert, fehlgeschlagene Extraktionen debuggt und vollständige Scraping-Pipelines aus natürlichsprachlichen Beschreibungen schreibt. Beginnen Sie mit der Wahl des richtigen Tools für Ihr Ziel, bauen Sie defensiv mit Fallback-Selektoren und Rate-Limiting, respektieren Sie immer robots.txt, und lassen Sie Cursor die Extraktionslogik generieren, damit Sie sich auf Datenqualität und Pipeline-Zuverlässigkeit konzentrieren können.