Mit den Grundlagen sowohl des statischen als auch des dynamischen Inhalt-Scrapings unter unserem Gürtel ist es Zeit, eine umfassendere Herausforderung anzugehen: mehrseitiges Crawling. Dieser Abschnitt konzentriert sich auf das effiziente Navigieren und Extrahieren von Daten von Websites mit mehreren miteinander verbundenen Seiten.
Es gibt zwei Hauptansätze zum Crawlen mehrseitiger Websites:
- Link-basiertes Crawling - Verfolgung von Links zwischen Seiten
- Sitemap-basiertes Crawling - Verwendung der sitemap.xml-Datei
Für Sitemap-Crawling bieten die meisten Websites eine sitemap.xml-Datei, die alle wichtigen URLs auflistet. Diese strukturierte XML-Datei enthält:
- Seiten-URLs
- Letzte Änderungsdaten
- Änderungshäufigkeit
- Prioritätswerte
Die Verwendung der Sitemap kann effizienter sein als Link-Crawling, da sie:
- Eine vollständige Liste der Seiten im Voraus bereitstellt
- Metadaten über Seitenwichtigkeit und Aktualität enthält
- Das Crawlen unnötiger Seiten vermeidet
- Serverlast reduziert
Aber für dieses Kapitel konzentrieren wir uns auf link-basiertes Crawling mit Crawlee, um einen Crawler für eine mehrseitige E-Commerce-Site zu erstellen. Crawlee übernimmt viele der Komplexitäten des Web-Crawlings für uns, einschließlich:
- Automatisches Queue-Management und URL-Deduplizierung
- Eingebaute Rate Limiting und Retry-Logik
- Konfigurierbare Request-Behandlung und Routing
- Datenspeicherung und -export
Die Seitenstruktur, die wir crawlen werden, sieht folgendermaßen aus:
Homepage
├── Kategorie: Elektronik
│ ├── Handys
│ ├── Laptops
│ └── Zubehör
├── Kategorie: Kleidung
│ ├── Herren
│ └── Damen
└── Empfohlene Produkte
Jede Produktseite hat verschiedene Layouts je nach Kategorie, aber wir müssen konsistente Informationen extrahieren:
// Beispiel Datenstruktur, die wir erstellen wollen
interface ProductData {
name: string;
price: number;
rating: { score: number, count: number };
features: string[];
status: string; // Auf Lager, Nicht auf Lager, etc.
}
interface ResultData {
categories: {
electronics: {
phones: ProductData[];
laptops: ProductData[];
accessories: ProductData[];
};
clothing: {
mens: {
shirts: ProductData[];
pants: ProductData[];
};
womens: {
dresses: ProductData[];
tops: ProductData[];
};
};
};
featured_products: FeaturedProduct[];
}
Schlüssel-Crawling-Konzepte mit Crawlee
- Request Queue Management
Crawlee übernimmt die Queue automatisch, aber hier ist, wie wir sie konfigurieren:
import { CheerioCrawler } from 'crawlee';
const crawler = new CheerioCrawler({
// Behandelt jeden Request
async requestHandler({ $, request, enqueueLinks }) {
// Seite verarbeiten
const data = extractPageData($);
// Automatisch neue URLs in die Queue einreihen, die auf der Seite gefunden wurden
await enqueueLinks({
selector: 'a',
baseUrl: request.loadedUrl,
});
},
// Concurrent Requests begrenzen
maxConcurrency: 10,
});
- URL-Behandlung
Crawlee bietet eingebaute URL-Behandlung und -Normalisierung:
await crawler.run([startUrl]);
// Oder mit mehr Konfiguration:
await crawler.addRequests([{
url: startUrl,
userData: {
label: 'start',
},
}]);
- Route-Behandlung
Routen verschiedene URLs zu spezifischen Handlers:
const crawler = new CheerioCrawler({
async requestHandler({ $, request }) {
const { label } = request.userData;
switch (label) {
case 'category':
return handleCategory($);
case 'product':
return handleProduct($);
default:
return handleHomepage($);
}
},
});
- Datensammlung
Crawlee bietet eingebaute Speicherung für gesammelte Daten:
const crawler = new CheerioCrawler({
async requestHandler({ $, pushData }) {
const productData = extractProduct($);
await pushData(productData);
},
});
Web-Crawling Best Practices
Während Crawlee viele Low-Level-Belange übernimmt, solltest du dennoch Folgendes beachten:
-
Konfiguration
- Setze angemessene Rate Limits
- Konfiguriere Retry-Strategien
- Setze aussagekräftige User-Agent-Strings
-
Fehlerbehandlung
- Verwende Crawlees eingebaute Fehlerbehandlung
- Implementiere benutzerdefinierte Error-Callbacks
- Logge aussagekräftige Diagnoseinformationen
-
Datenorganisation
- Strukturiere deine Daten konsistent
- Verwende Request-Labels für Routing
- Nutze Crawlees Dataset-Features
-
Ressourcenverwaltung
- Konfiguriere maxConcurrency angemessen
- Verwende maxRequestsPerCrawl wenn nötig
- Überwache Speicherverbrauch
Die Herausforderung
Deine Aufgabe ist es, einen Crawlee-basierten Crawler zu erstellen, der:
- Bei der Homepage startet und alle Produktkategorien entdeckt
- Jede Kategorie- und Unterkategorieseite besucht
- Produktinformationen aus jedem Listing extrahiert
- Daten in einem strukturierten Format organisiert
- Produkte behandelt, die an mehreren Stellen erscheinen (z.B. empfohlen und Kategorie)
Die Site enthält etwa 25-30 Produkte über verschiedene Kategorien hinweg, mit variierenden Layouts und Informationsstrukturen. Dein Crawler sollte einen umfassenden Datensatz produzieren, der die hierarchische Beziehung zwischen Kategorien und Produkten aufrechterhält.
Deine Lösung testen
Teste auf:
- Vollständigkeit: Hast du alle Produkte gefunden?
- Genauigkeit: Sind die extrahierten Daten korrekt?
- Struktur: Sind die Daten richtig organisiert?
- Effizienz: Wie viele Requests hast du gemacht?
Das gelöste Beispiel in _solved/chapter6/
bietet eine Referenzimplementierung mit Crawlee. Studiere es, um zu verstehen, wie man die Features der Bibliothek für effizientes mehrseitiges Crawling und Datenorganisation nutzt.
Frohes Crawling!