Bieraanbiedingen Scrapen met TypeScript en Crawlee

Samen met een partner ben ik begonnen aan een nieuw project: BierExperts. Een leuk onderwerp natuurlijk — en voor mij ook een goede reden om weer eens met Kotlin, TypeScript en PHP aan de slag te gaan. Mijn verantwoordelijkheid binnen het project zijn nu de bieraanbiedingen. Wat ik hiervoor doe? Ik scrape de grootste supermarkten in Nederland en verzamel de actuele aanbiedingen.
Klinkt simpel, toch?
Nou, eerlijk gezegd viel het me in de praktijk toch tegen. Niet vanwege de techniek, maar vooral door al het gepriegel om de juiste informatie uit de DOM-structuur te halen, inconsistenties te verwerken, en alles strakker op te slaan.
Crawling met Crawlee
Om het scrapen op te zetten gebruik ik Crawlee. Software die het je makkelijk maakt om een solide crawler-architectuur op te zetten.
Voor elke supermarkt die ik toevoeg, maak ik een crawler aan op basis van een simpele interface:
export abstract class BaseCrawler {
protected supermarketId: string;
constructor(supermarketId: string) {
this.supermarketId = supermarketId;
}
abstract setup(): Promise<void>;
abstract crawl(): Promise<string>;
}
Niet spannend, maar wel effectief. Deze abstractie zorgt ervoor dat elke supermarkt-crawler dezelfde structuur volgt, en dat ik gemakkelijk meerdere crawlers naast elkaar kan draaien. De setup is bedoeld om zaken als datasets bijvoorbeeld te initialiseren.
Een implementatie ziet er dan bijvoorbeeld zo uit:
export class SupermarktXCrawlerWrapper extends BaseCrawler {
constructor() {
super('jumbo');
}
async setup(): Promise<void> {
console.log('Setting up Jumbo crawler...');
try {
const dataset = await Dataset.open(datasetId('SupermarktX'));
await dataset.drop();
} catch (error) {
}
}
async crawl(): Promise<string> {
console.log('Starting Jumbo crawler...');
// Run the crawler and get the dataset ID
const datasetId = await SupermarktXCrawler();
console.log(`Jumbo crawler completed, dataset ID: ${datasetId}`);
return datasetId;
}
}
Deze aanpak maakt het eenvoudig om de crawlers overzichtelijk te houden en logisch te scheiden per supermarkt.
Van Dataset naar Backend
Na het draaien van de crawlers worden de datasets gevuld met de ruwe aanbiedingen. Deze data wordt vervolgens één voor één gepost naar onze backend.
Mocht je zelf interesse hebben om zoiets te doen, of gewoon met crawlee te spelen dan raad ik het je aan. Het simpel en toch effectief.
Proost!
