Als enthousiaste ultramarathonloper sta ik vaak voor een veelvoorkomende uitdaging: hoe kan ik mijn eindtijd inschatten voor langere wedstrijden die ik nog niet heb geprobeerd? Toen ik hierover sprak met mijn coach, stelde hij een praktische aanpak voor: kijk naar lopers die zowel een race hebben voltooid die ik heb gelopen als de race waarop ik mik. Deze correlatie kan waardevolle inzichten bieden in mogelijke eindtijden. Maar handmatig zoeken door wedstrijduitslagen zou ontzettend tijdrovend zijn.
Dit leidde ertoe dat ik Race Time Insights heb ontwikkeld, een tool die automatisch wedstrijduitslagen vergelijkt door atleten te vinden die beide evenementen hebben voltooid. De applicatie schraapt wedstrijduitslagen van platforms zoals UltraSignup en Pacific Multisports, waardoor hardlopers twee race-URL’s kunnen invoeren en kunnen zien hoe andere atleten hebben gepresteerd bij beide evenementen.
Het bouwen van deze tool liet me zien hoe krachtig het App Platform van DigitalOcean kon zijn. Door Puppeteer te gebruiken met headless Chrome in Docker-containers kon ik me richten op het oplossen van het probleem voor hardlopers terwijl het App Platform alle infrastructurele complexiteit afhandelde. Het resultaat was een robuuste, schaalbare oplossing die de hardloopgemeenschap helpt bij het nemen van op data gebaseerde beslissingen over hun wedstrijddoelen.
Na het bouwen van Race Time Insights wilde ik een handleiding maken waarin andere ontwikkelaars leren hoe ze dezelfde technologieën kunnen benutten – Puppeteer, Docker-containers en het DigitalOcean App Platform. Uiteraard moet je bij het werken met externe gegevens letten op zaken als het hanteren van het aantal verzoeken en de gebruiksvoorwaarden.
Betreed Project Gutenberg. Met zijn uitgebreide collectie van boeken in het publieke domein en duidelijke gebruiksvoorwaarden is het een ideaal kandidaat om deze technologieën te demonstreren. In deze post zullen we verkennen hoe je een boekzoektoepassing kunt bouwen met behulp van Puppeteer in een Docker-container, ingezet op App Platform, terwijl we de beste praktijken volgen voor toegang tot externe data.
Project Gutenberg Boek Zoeken
Ik heb een webtoepassing gebouwd en gedeeld die verantwoordelijk boekinformatie van Project Gutenberg scrapet. De app, die je kunt vinden in deze GitHub-opslagplaats, stelt gebruikers in staat om te zoeken door duizenden boeken in het publieke domein, gedetailleerde informatie over elk boek te bekijken en verschillende downloadformaten te openen. Wat dit bijzonder interessant maakt, is hoe het verantwoorde web scrapenpraktijken demonstreert en tegelijkertijd echte waarde biedt aan gebruikers.
Een Goede Digitale Burger zijn
Als je een web scraper bouwt, is het cruciaal om goede praktijken te volgen en zowel technische als juridische grenzen te respecteren. Project Gutenberg is een uitstekend voorbeeld om deze principes te leren omdat:
- Het heeft duidelijke gebruiksvoorwaarden.
- Het biedt robots.txt richtlijnen
- Zijn inhoud is expliciet in het publieke domein
- Het profiteert van een verbeterde toegankelijkheid tot zijn bronnen
Onze implementatie omvat verschillende best practices:
Rate Limiting
Voor demonstratiedoeleinden implementeren we een eenvoudige rate limiter die ervoor zorgt dat er minimaal 1 seconde tussen verzoeken zit:
Deze implementatie is opzettelijk vereenvoudigd voor het voorbeeld. Het gaat uit van een enkele toepassingsinstantie en slaat de status op in het geheugen, wat niet geschikt zou zijn voor productiegebruik. Meer robuuste oplossingen zouden Redis kunnen gebruiken voor gedistribueerd rate limiting of queue-gebaseerde systemen implementeren voor betere schaalbaarheid.
Deze rate limiter wordt gebruikt vóór elk verzoek naar Project Gutenberg:
Duidelijke Bot Identificatie
Een aangepaste User-Agent helpt websitebeheerders te begrijpen wie hun site bezoekt en waarom. Deze transparantie stelt hen in staat om:
- contact met u op te nemen als er problemen zijn
- botverkeer apart van menselijke gebruikers te monitoren en analyseren
- mogelijk betere toegang of ondersteuning te bieden aan legitieme scrapers
Efficiënt Resourcebeheer
Chrome kan geheugenintensief zijn, vooral bij het uitvoeren van meerdere exemplaren. Het correct sluiten van browserpagina’s na gebruik voorkomt geheugenlekken en zorgt ervoor dat uw toepassing efficiënt draait, zelfs bij het verwerken van veel verzoeken:
Door deze werkwijzen te volgen, creëren we een scraper die zowel effectief is als respectvol ten opzichte van de resources die het gebruikt. Dit is met name belangrijk bij het werken met waardevolle openbare bronnen zoals Project Gutenberg.
Web Scraping in de Cloud
De applicatie maakt gebruik van moderne cloudarchitectuur en containerisatie via het App Platform van DigitalOcean. Deze aanpak zorgt voor een perfecte balans tussen ontwikkelingssimpliciteit en productiebetrouwbaarheid.
De kracht van het App Platform
Het App Platform stroomlijnt het implementatieproces door het volgende te beheren:
- Webserverconfiguratie
- SSL-certificaatbeheer
- Beveiligingsupdates
- Load balancing
- Resource monitoring
Dit stelt ons in staat om ons te richten op de applicatiecode terwijl het App Platform de infrastructuur beheert.
Headless Chrome in een Container
De kern van onze schrapende functionaliteit maakt gebruik van Puppeteer, dat een API op hoog niveau biedt om Chrome programmatisch te besturen. Zo stellen we Puppeteer in en gebruiken we het in onze toepassing:
Deze setup stelt ons in staat om:
- Chrome uit te voeren in headless modus (geen GUI nodig)
- JavaScript uit te voeren in de context van webpagina’s
- Browserresources veilig te beheren
- Betrouwbaar te werken in een gecontaineriseerde omgeving
De setup bevat ook verschillende belangrijke configuraties voor het uitvoeren in een gecontaineriseerde omgeving:
- Correcte Chrome-argumenten: Essentiële vlaggen zoals
--no-sandbox
en--disable-dev-shm-usage
voor het uitvoeren in containers - Omgevingsbewust pad: Gebruikt het juiste pad naar het Chrome-binair vanuit omgevingsvariabelen
- Resourcebeheer: Stelt viewportgrootte in en schakelt onnodige functies uit
- Professionele botidentiteit: Duidelijke gebruikersagent en HTTP-headers die onze scraper identificeren
- Foutafhandeling: Juiste opruiming van browserpagina’s om geheugenlekken te voorkomen
Hoewel Puppeteer het gemakkelijk maakt om Chrome programmatisch te besturen, vereist het uitvoeren ervan in een container de juiste systeemafhankelijkheden en configuratie. Laten we eens bekijken hoe we dit opzetten in onze Docker-omgeving.
Docker: Zorgen voor consistente omgevingen
Een van de grootste uitdagingen bij het implementeren van webscrapers is ervoor zorgen dat ze op dezelfde manier werken in ontwikkeling en productie. Uw scraper kan perfect werken op uw lokale machine, maar falen in de cloud vanwege ontbrekende afhankelijkheden of verschillende systeemconfiguraties. Docker lost dit op door alles wat de applicatie nodig heeft – van Node.js tot Chrome zelf – te verpakken in een enkele container die overal identiek draait.
Ons Docker-bestand stelt deze consistente omgeving in:
FROM node:18-alpine
# Installeer Chromium en afhankelijkheden
RUN apk add --no-cache \
chromium \
nss \
freetype \
harfbuzz \
ca-certificates \
ttf-freefont \
dumb-init
# Stel omgevingsvariabelen in
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
PUPPETEER_DISABLE_DEV_SHM_USAGE=true
De op Alpine gebaseerde image houdt onze container lichtgewicht terwijl het alle noodzakelijke afhankelijkheden bevat. Wanneer u deze container uitvoert, of het nu op uw laptop is of in het App Platform van DigitalOcean, krijgt u dezelfde omgeving met alle juiste versies en configuraties om headless Chrome uit te voeren.
Van Ontwikkeling tot Implementatie
Laten we doornemen hoe we dit project aan de praat krijgen:
1. Lokale Ontwikkeling
Ten eerste, fork de voorbeeldrepository naar je GitHub-account. Dit geeft je je eigen kopie om mee te werken en van te implementeren. Clone vervolgens je fork lokaal:
# Clone je fork
git clone https://github.com/YOUR-USERNAME/doappplat-puppeteer-sample.git
cd doappplat-puppeteer-sample
# Bouw en draai met Docker
docker build -t gutenberg-scraper .
docker run -p 8080:8080 gutenberg-scraper
2. Het Begrijpen van de Code
De applicatie is opgebouwd rond drie hoofdcomponenten:
-
Boekenservice: Beheert web scraping en gegevensextractie
-
Express Server: Beheert routes en rendert sjablonen
-
Frontend Weergaven: Schone, responsieve UI met behulp van Bootstrap
<div class="card book-card h-100"> <div class="card-body"> <span class="badge bg-secondary downloads-badge"> <%= book.downloads.toLocaleString() %> downloads </span> <h5 class="card-title"><%= book.title %></h5> <!-- ... meer UI-elementen ... --> </div> </div>
3. Implementatie naar DigitalOcean
Nu je een fork van het repository hebt, is implementeren naar het DigitalOcean App Platform eenvoudig:
- Maak een nieuwe App Platform-toepassing
- Verbind met je geforkte repo
- Verwijder in resources de tweede resource (dat is geen Dockerfile); dit wordt automatisch gegenereerd door App Platform en is niet nodig
- Implementeer door op Resources maken te klikken
De toepassing wordt automatisch gebouwd en geïmplementeerd, waarbij App Platform alle infrastructuurdetails afhandelt.
Conclusie
Deze Project Gutenberg-scraper toont hoe je een praktische webtoepassing bouwt met behulp van moderne cloudtechnologieën. Door Puppeteer voor webscraping, Docker voor containerisatie en DigitalOcean’s App Platform voor implementatie te combineren, hebben we een oplossing gecreëerd die zowel robuust als gemakkelijk te onderhouden is.
Het project dient als een sjabloon voor jouw eigen webscraping-toepassingen, waarbij wordt getoond hoe je browserautomatisering kunt beheren, resources efficiënt kunt beheren en naar de cloud kunt implementeren. Of je nu een gegevensverzamelingsinstrument bouwt of gewoon meer te weten wilt komen over gecontaineriseerde toepassingen, dit voorbeeld biedt een solide basis om op voort te bouwen.
Bekijk het project op GitHub om meer te leren en je eigen exemplaar te implementeren!