Web Scraping kann anfangs einschüchternd wirken, aber wie jede Fähigkeit lernt man es am besten durch praktische Übungen. In diesen ersten drei Kapiteln erkunden wir die Grundlagen des Extrahierens von Daten aus statischen HTML-Seiten.
Kapitel 1: Der HTML-Scraper Chad
Unsere Reise beginnt mit dem einfachstmöglichen Szenario – dem Extrahieren von Text aus einer einfachen HTML-Seite. Dieses Kapitel macht dich mit den Kernkonzepten vertraut:
- HTTP-Anfragen stellen, um Webseiten abzurufen
- HTML-Inhalte in einen Parser laden
- Grundlegende DOM-Auswahl mit CSS-Selektoren
Auch wenn das Beispiel trivial erscheinen mag (es ist schließlich nur ein „Hello World“!), legt es das Fundament für alles, was danach kommt.
<!-- Example HTML structure -->
<div class="content">
<p>Some text we want to extract</p>
</div>
Hier ist ein kleiner Vorgeschmack auf das, womit wir arbeiten:
// Basic concepts (not the solution!)
import * as cheerio from 'cheerio';
// Loading HTML content
const $ = cheerio.load(htmlContent);
// Using CSS selectors
const text = $('p').text(); // Selects all <p> tags
const specific = $('.content p').text(); // More specific selection
Kapitel 2: Strukturierte Daten
Jetzt wird es interessanter, denn wir tauchen in eine simulierte Produktseite eines E-Commerce-Shops ein. Hier haben wir es mit mehreren Elementen zu tun, die ähnliche Strukturen besitzen:
<!-- Example product structure (simplified) -->
<div class="product">
<h2>Product Name</h2>
<span class="price">$99.99</span>
<div class="specs">
<ul>
<li>Size: M</li>
<li>Color: Blue</li>
</ul>
</div>
</div>
Wenn du mit strukturierten Daten wie diesen arbeitest, solltest du an Folgendes denken:
// Conceptual approach (not the solution!)
$('.product').each((index, element) => {
// For each product, we might want to:
// 1. Extract the basic info
const name = $(element).find('h2').text();
// 2. Parse nested data
const specs = $(element).find('.specs li');
// 3. Structure the output
const data = {
name,
specs: specs.map(/* ... */),
};
});
Profi-Tipp: Bevor du überhaupt Code schreibst, nimm dir Zeit, die HTML-Struktur zu analysieren. Achte auf Muster in der Organisation der Daten – gibt es konsistente Klassennamen? Wie stehen Eltern- und Kindelemente zueinander?
Kapitel 3: KI-gestütztes Scraping
Jetzt wird es richtig spannend! Während die vorherigen Herausforderungen uns klassische Scraping-Techniken vermittelt haben, führt Kapitel 3 einen modernen Ansatz ein: KI-gestütztes Web Scraping. Wir stehen vor einem Albtraum-Szenario – uneinheitliche HTML-Strukturen, verschleierte Klassennamen und mehrere Framework-Muster, alles bunt durcheinander gemischt.
Schauen wir uns an, was diese Herausforderung besonders macht:
<!-- Traditional product structure -->
<div data-testid="product-container-1" class="_3xj_item">
<h2 data-qa="name">Red Sneakers</h2>
<span data-price-current="5999">$59.99</span>
</div>
<!-- React-style component -->
<div class="ProductCard-root-1a2b3c">
<div class="ProductCard-title-4d5e6f">Pink Walking Shoes</div>
<div class="ProductCard-pricing-7g8h9i">$84.99</div>
</div>
<!-- Vue-style template -->
<div data-v-abcdef class="product">
<h2 data-v-abcdef>Navy Boat Shoes</h2>
<span data-v-abcdef>$79.99</span>
</div>
Klassische Scraping-Ansätze hätten hier Schwierigkeiten, weil:
- Klassennamen zufällig generiert oder frameworkspezifisch sind
- Datenstrukturen sich zwischen Produkten unterscheiden
- Unterschiedliche Frameworks unterschiedliche Muster verwenden
- Die semantische Bedeutung im Markup verloren geht
Hier kommt KI zur Rettung. Anstatt brüchige Selektoren zu schreiben, können wir in natürlicher Sprache beschreiben, was wir wollen, und die KI die Mustererkennung übernehmen lassen. Zu den zentralen Konzepten in diesem Kapitel gehören:
- Prompt Engineering für Web Scraping
- Einsatz von KI zum Verständnis semantischer Bedeutung
- Umgang mit uneinheitlichen Datenstrukturen
- Umgang mit frameworkspezifischem Markup
- Wahrung der Datenkonsistenz über unterschiedliche Muster hinweg
KI ist zwar keine Magie, aber sie ist hervorragend bei Aufgaben, die Mustererkennung und Anpassungsfähigkeit erfordern. Das macht sie besonders wertvoll für das Scrapen moderner Webanwendungen, bei denen konsistente Markup-Muster nicht garantiert werden können.
Ein Hinweis zur Nutzung von KI
Denk daran: KI-Unterstützung bedeutet nicht vollständig automatisierte Lösungen. Die besten Ergebnisse entstehen durch die Kombination aus:
- Klarer Problemdefinition
- Gut strukturierten Prompts
- Datenvalidierung
- Menschlicher Kontrolle
Deine Herausforderung wird darin bestehen, Prompts zu formulieren, die der KI helfen, sowohl die Struktur als auch die Absicht dessen zu verstehen, was du extrahieren möchtest.
Bereit, traditionelles Web-Scraping-Wissen mit modernen KI-Fähigkeiten zu verbinden? Finden wir heraus, wie KI selbst beim chaotischsten HTML helfen kann!
Hinweise
- Experimentiere mit verschiedenen CSS-Selektoren:
// Different ways to select elements
$('.class') // By class
$('#id') // By ID
$('div > p') // Direct children
$('div p') // All descendants
$('[data-type="x"]') // By attribute
- Versuche, das Ausgabeformat zu verändern
- Denke über Fehlerbehandlung und Sonderfälle nach
- Überlege, wie deine Lösung mit größeren Datensätzen skalieren könnte
Den gesamten Code, den du für den Einstieg brauchst, findest du im Projekt-Repository. Clone es, richte deine Umgebung ein und leg mit dem Scrapen los!
git clone https://github.com/jonaylor89/housefly.git
cd housefly
npm install
Starte die Kapitel-Server lokal – jedes Kapitel läuft auf seinem eigenen Port (3001–3011):
turbo dev
Bearbeite dann deinen Scraper in exercises/chapter-NN/starter/src/index.ts und validiere ihn:
npm run validate -- <chapter>
Du suchst nach Hinweisen? Führe npm run hint -- <chapter> aus, um schrittweise Hilfestellung zu bekommen. Das Quell-HTML für jede Herausforderung findest du im Verzeichnis apps/chapter{n}/, und Referenzlösungen liegen in exercises/chapter-NN/solution/src/. Studiere die Struktur, plane deinen Ansatz und denk daran – jede Expertin und jeder Experte war einmal Anfänger.
Denk daran, verantwortungsvoll mit deinen Anfragen umzugehen:
// Basic error handling example
async function fetchPage(url: string) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.text();
} catch (error) {
console.error('Failed to fetch page:', error);
throw error;
}
}
Viel Spaß beim Scrapen!