Meteen naar de inhoud

Applicaties van één pagina schrapen met Toneelschrijver: een uitgebreide handleiding

Single-page-applicaties, of SPA's, zijn de norm geworden voor moderne webontwikkeling. In tegenstelling tot traditionele sites met meerdere pagina's werken SPA's de inhoud dynamisch bij en geven ze pagina's weer met behulp van JavaScript zonder dat de volledige pagina opnieuw hoeft te worden geladen. Dit creëert een soepele, app-achtige ervaring voor gebruikers.

De toegenomen afhankelijkheid van JavaScript aan de clientzijde en het asynchrone laden van gegevens brengt echter unieke uitdagingen met zich mee bij het verzamelen van gegevens uit applicaties met één pagina. Traditionele scrapingtools schieten tekort omdat ze zijn ontworpen voor statische sites en HTML-parsing.

In deze uitgebreide gids van meer dan 3200 woorden leert u beproefde technieken om de veelvoorkomende obstakels aan te pakken die u tegenkomt bij het schrappen van moderne SPA's met behulp van Playwright.

Waarom het schrapen van SPA's een uitdaging is

Voordat we in oplossingen duiken, is het belangrijk om te begrijpen wat het überhaupt moeilijk maakt om applicaties van één pagina te schrapen.

Intensief gebruik van JavaScript aan de clientzijde

De HTML die in eerste instantie door de server wordt aangeboden, is in wezen een statische schil van de pagina. De daadwerkelijke inhoud wordt dynamisch gegenereerd en via JavaScript aan de clientzijde weergegeven. Dit betekent dat veel van de gegevens alleen in JavaScript-objecten en DOM-elementen voorkomen en niet in de oorspronkelijke HTML-bron.

Asynchroon gegevens laden

SPA's halen regelmatig nieuwe inhoud asynchroon op de achtergrond op en werken de pagina bij zonder volledig opnieuw te laden. De gegevens zijn vaak niet vooraf beschikbaar wanneer de pagina voor het eerst wordt geladen.

Volgens statistieken van Radware doet de gemiddelde webpagina tijdens het renderen meer dan 100 verzoeken aan externe bronnen.

JaarGemiddelde paginaverzoeken
201133
201656
2019105

Bij intensief gebruik van technologieën als AJAX kunnen de gegevens die u nodig hebt, mogelijk nog steeds op de achtergrond worden geladen wanneer u deze probeert te extraheren. Dit leidt ertoe dat onvolledige gegevens worden geschraapt.

Dynamische DOM-manipulatie

De componenten en elementen die op een SPA worden weergegeven, kunnen snel veranderen als reactie op gebruikersinvoer. Inhoud wordt dynamisch gegenereerd, toegevoegd, verwijderd of bijgewerkt terwijl de gebruiker met de app communiceert.

Proberen om elementen te targeten op basis van hun initiële DOM-positie is kwetsbaar omdat deze zo vaak verschuift.

Afhankelijkheid van API's en AJAX-verzoeken

SPA's maken op grote schaal gebruik van REST API's, GraphQL, WebSockets en AJAX-verzoeken om gegevens op te halen van backend-servers. De inhoud wordt vervolgens aan de clientzijde weergegeven.

Deze gegevensuitwisseling tussen client en server is onzichtbaar voor traditionele scraping-benaderingen die alleen de initiële HTML-reactie zien.

Geauthenticeerde sessies en status

Bij complexe SPA's moeten gebruikers vaak inloggen voordat ze toegang krijgen tot privé-inhoud en -gegevens. Deze authenticatiestatus moet correct worden gehandhaafd in scraping-scripts.

Cookies die sessie-ID's, gebruikers-ID's en tokens opslaan, moeten worden behandeld om een ​​geverifieerde gebruikerssessie na te bootsen.

De noodzaak van JavaScript-uitvoering

In tegenstelling tot statische sites is het puur parseren van HTML niet voldoende voor SPA's. De pagina moet worden weergegeven door JavaScript uit te voeren in een browserachtige omgeving om de uiteindelijke gegevensstructuur te genereren.

Headless browsers zoals Playwright bieden deze mogelijkheid om de realistische eindgebruikerservaring te creëren die nodig is om SPA's te schrapen.

Deze uitdagingen maken effectief SPA-scrapen heel anders dan conventioneel webscrapen. Laten we nu eens kijken hoe Playwright u kan helpen deze obstakels te overwinnen.

Waarom toneelschrijver gebruiken voor het schrapen van SPA's?

Playwright is een Node.js-bibliotheek voor het automatiseren van populaire webbrowsers zoals Chromium, Firefox en WebKit. De belangrijkste mogelijkheden die relevant zijn voor SPA-scrapen zijn onder meer:

Headless browserautomatisering

Toneelschrijver kan browsers aansturen zonder een zichtbare gebruikersinterface weer te geven, de zogenaamde headless-modus. Hierdoor kunnen zware JavaScript-pagina's worden uitgevoerd om gegevens in te vullen.

Wachten op elementen en omstandigheden

Intelligente ingebouwde wachtmechanismen voorkomen scraping-fouten door te wachten tot elementen of functies de gewenste status hebben bereikt voordat er interactie plaatsvindt.

Het bespotten van API-verzoeken

Met Playwright kunnen verzoeken worden onderschept en worden gereageerd met nepgegevens in plaats van echte API's aan te roepen. Dit maakt het schrapen van AJAX-gegevens mogelijk.

Responsief testen

Emuleer mobiele apparaten, geografische gebieden en CPU-beperking om te voldoen aan responsieve ontwerptestbehoeften.

Trace-viewer

Visualiseer Playwright-scripts om de exacte browserinteracties te begrijpen en problemen te diagnosticeren.

Automatische afhandeling van pop-ups en dialogen

Playwright verwerkt automatisch waarschuwingen, bevestigingen, prompts, auth-verzoeken en downloads, waardoor de scriptlogica wordt vereenvoudigd.

Selectors en DOM API

Rijke API om gegevens te extraheren via CSS-selectors of om DOM-elementen rechtstreeks te doorkruisen zoals een gewone webpagina.

Deze mogelijkheden maken Playwright zeer geschikt voor de uitdagingen van webapplicaties met één pagina. De belangrijkste alternatieven zoals Puppeteer, Selenium en HtmlUnit, hoewel nuttig voor algemene browsertests, missen de robuuste functieset van Playwright voor effectief SPA-scrapen.

Laten we vervolgens enkele codevoorbeelden bekijken die sleutelschraappatronen demonstreren met behulp van Playwright.

Patronen voor SPA's schrapen met Playwright

Hieronder zullen we enkele algemene schraptechnieken onderzoeken om specifieke SPA-uitdagingen te overwinnen.

Wacht tot de inhoud is geladen

Een van de meest fundamentele uitdagingen bij het schrapen van SPA is het laden van de inhoud voordat deze wordt uitgepakt.

In plaats van te proberen gegevens onmiddellijk te extraheren, moeten we wachten tot de asynchrone JavaScript-weergave klaar is met het vullen van de pagina.

Toneelschrijver page.waitForSelector() methode maakt het mogelijk te wachten tot een specifieke selector verschijnt voordat verdere opdrachten worden uitgevoerd:

// Navigate to SPA
await page.goto(‘https://spa.com‘);

// Wait for content to load
await page.waitForSelector(‘.content‘);

// Extract data now that .content exists
const data = await page.$eval(‘.content‘, elem => elem.textContent); 

Dit wacht tot het element met klasse content is beschikbaar in de DOM voordat de tekstinhoud wordt geëxtraheerd.

Zonder dit wachten, .content bestaat mogelijk nog niet als het asynchroon laden nog steeds fouten veroorzaakt. Deze eenvoudige vertraging geeft de SPA de tijd om nieuwe gegevens op te halen en weer te geven, waardoor daaropvolgende extractie mogelijk wordt.

WachtVoorFunctie

In sommige gevallen moeten we mogelijk wachten tot complexere JavaScript-voorwaarden waar zijn, in plaats van op een eenvoudige selector. Hier kunnen we gebruik van maken page.waitForFunction():

// Wait for data to load
await page.waitForFunction(() => {
  return window.store.articles.length > 0 ;
});

// Store now has loaded articles
const articles = await page.evaluate(() => {
  return window.store.articles; 
});

Hiermee wordt de pagina ondervraagd tot de gewoonte window.store.articles voorwaarde retourneert waar voordat de gegevens worden gelezen.

Intelligent wachten op selectors en voorwaarden voorkomt scraping-fouten als gevolg van het asynchroon laden van paginagegevens.

Behandel dynamische inhoudsupdates

Apps met één pagina kunnen de inhoud dynamisch bijwerken als reactie op gebruikersinvoer en gebeurtenissen zonder de pagina opnieuw te laden.

Een veelvoorkomend voorbeeld is oneindig scrollen waarbij nieuwe elementen worden toegevoegd wanneer de gebruiker naar beneden scrolt.

Om dynamisch toegevoegde elementen te verwerken, kunnen we luisteren naar DOM-veranderingen met behulp van mutatiewaarnemers:

// Monitor mutations
await page.evaluate(() => {

  const observer = new MutationObserver(mutations => {
    console.log(‘Added nodes:‘, mutations[0].addedNodes);
  });

  observer.observe(document, { 
    childList: true,
    subtree: true
  });

});

De observer wordt op de hoogte gesteld wanneer er nieuwe elementen aan de paginatekst worden toegevoegd. We kunnen dan onze schraplogica activeren als reactie op deze mutaties.

Hierdoor kunt u zich aanpassen aan inhoudsupdates in plaats van alleen het laden van de eerste pagina af te handelen.

Mock-API-verzoeken

SPA's maken op grote schaal gebruik van REST- en GraphQL-API's om gegevens aan de clientzijde op te halen.

Om deze verzoeken te onderscheppen, kunnen we in Playwright routes definiëren om reacties te imiteren:

await page.route(‘/api/articles‘, route => {
  route.fulfill({
    status: 200,
    body: JSON.stringify([
      {title: ‘Article 1‘},
      {title: ‘Article 2‘}  
    ])
  }); 
});

// Mock response will be returned from /api/articles
await page.goto(‘/page-that-calls-api‘) 

Wanneer de SPA probeert te bellen /api/articles, zal onze handler reageren met het gedefinieerde nep-antwoord in plaats van de echte API te gebruiken.

Hierdoor is het mogelijk om API-gegevens te schrapen zonder bijwerkingen. We kunnen robuuste antwoorden bouwen om verschillende scenario's aan te kunnen die onze SPA-code kan verwachten.

Authenticeer sessie

Het schrappen van privéaccountgebieden in SPA's vereist een juiste afhandeling van de authenticatie.

Een eenvoudige aanpak is om normaal in te loggen via de gebruikersinterface voordat u gaat scrappen:

// Navigate to login page
await page.goto(‘/login‘);

// Enter credentials and submit form 
await page.type(‘#email‘, ‘[email protected]‘);
await page.type(‘#password‘, ‘secret‘);
await page.click(‘#submit‘);

// Session now authenticated
// Crawl member pages 

Dit maakt gebruik van de mogelijkheden van Playwright om het invullen van formulieren en klikken te automatiseren, waardoor een geverifieerde browsersessie ontstaat.

Voor de beste resultaten logt u in in a beforeAll haak en hergebruik de browser en page context tijdens tests om cookies te delen.

Responsieve ontwerpafhandeling

SPA's passen hun lay-out en inhoud vaak aan voor verschillende apparaatformaten. Om deze responsieve scenario's te testen, kunnen we mobiele browsers emuleren met behulp van page.emulate():

await page.emulate({
  viewport: {
    width: 400,  
    height: 800
  },
  userAgent: ‘...‘,
});

Door een iPhone-viewport en user-agent in te stellen, wordt de pagina weergegeven zoals een mobiel apparaat dat zou doen.

Combineer emulatie met waitForSelector en u kunt op betrouwbare wijze omgaan met responsieve ontwerpen.

Door verschillende omgevingen te emuleren, zorgt u ervoor dat uw scraper zich aanpast aan de SPA op desktop en mobiel.

Scraper Helper-bibliotheken

Diensten zoals Apify en SchrapenBee bieden op Playwright gebaseerde bibliotheken die op intelligente wijze omgaan met het wachten op inhoud, het scrollen automatiseren voor dynamische pagina-updates, verzoeken om vertraging en meer.

Deze tools kunnen het schrijven van robuuste SPA-scraping-scripts zelf vereenvoudigen.

Praktisch toneelschrijver Scraper-script

Laten we deze benaderingen nu samenbrengen in een echte wereldschraper voor een hypothetische SPA:

const { chromium } = require(‘playwright‘);

(async () => {

  const browser = await chromium.launch();
  const page = await browser.newPage();  

  // Login to scrape private content
  await page.goto(‘/login‘);
  await page.type(‘#email‘, ‘[email protected]‘);
  await page.type(‘#password‘, ‘secret‘); 
  await page.click(‘#submit‘);

  await page.waitForNavigation();

  // Navigate to SPA
  await page.goto(‘/app‘);

  // Wait for content to load
  await page.waitForSelector(‘.content‘);

  // Monitor mutations
  page.evaluate(() => {
    new MutationObserver().observe(document, {
      childList: true 
    });    
  });

  // Mock API response
  page.route(‘/api/articles‘, route => {
    route.fulfill({ /*...mock response...*/ }); 
  });

  // Extract content 
  const data = await page.evaluate(() => {
    const content = document.querySelector(‘.content‘);
    return content.innerText;
  });

  console.log(data);

  await browser.close();

})();

Dit script logt in op de privé-app, wacht tot de geverifieerde inhoud is geladen, verwerkt dynamische mutaties, bespot de API-reactie en extraheert de gegevens naar const data.

De technieken kunnen worden aangepast om robuuste schrapers te ontwikkelen voor echte SPA's.

SPA's op schaal schrapen

Voor grote SPA's kan het handmatig schrapen van slechts een paar pagina's eenvoudig genoeg zijn. Er zijn echter slimme oplossingen nodig bij het crawlen van duizenden of miljoenen pagina’s.

API-services schrapen

Webscraping-API's zoals SchraperAPI omgaan met browserautomatisering, cookies, proxy's en rotaties op schaal. Dit vereenvoudigt het schrapen van JavaScript-zware sites, inclusief SPA's.

Browserboerderijen zonder hoofd

Diensten zoals Browserloos en Sangfor Cloud-browser bieden grote clusters van Playwright- en Puppeteer-instanties die toegankelijk zijn via API's. Deze parallelle instanties maken het gedistribueerd schrapen van SPA's op schaal mogelijk.

Gehoste crawlers

In plaats van uw eigen scraping-infrastructuur te runnen, hosten crawlers zoals Crawlera en proxycrawl omgaan met het orkestreren van browsers, proxy's en automatisering om complexe sites te crawlen.

Webscraping-bots

Tools zoals Fantoombuster, Dexi.io en ParseHub bieden point-and-click-configuratie van schrapers voor SPA's zonder codering. Deze bots detecteren automatisch pagina-inhoud, wachttijden, klikken enz. waardoor installatie zonder code mogelijk is.

Afhankelijk van uw gebruiksscenario kan het gebruik van een van deze zakelijke services effectiever zijn dan het bouwen van uw eigen scrapinginfrastructuur voor grootschalige SPA-crawling.

Een eenvoudiger alternatief: Crawlee

Crawlee biedt een innovatieve webcrawler als service voor JavaScript-gerenderde sites.

Het verwerkt automatisch veelvoorkomende scraping-uitdagingen, zoals:

  • Wachten tot elementen of URL's zijn geladen voordat ze worden uitgepakt
  • Sessies authenticeren en cookies opslaan
  • Het onderscheppen van API-verzoeken en het verwerken van AJAX-gegevens
  • Bladeren door oneindige scrollpagina's
  • Mislukte extracties opnieuw uitvoeren om de veerkracht te verbeteren

Crawlee kan out-of-the-box door complexe SPA's kruipen zonder dat hij Playwright-scripts hoeft te coderen voor wachten, authenticatie, AJAX-afhandeling enz.

Belangrijkste mogelijkheden:

  • Configureer via een visuele interface in plaats van te coderen
  • Wacht automatisch op URL's en selectors voordat gegevens worden geëxtraheerd
  • Bij stateful crawlen worden cookies over verschillende pagina's overgedragen
  • Onderschepping van API-verzoeken om XHR-, Fetch- en JSON-gegevens te verwerken
  • Headless Chrome-weergave standaard
  • Visuele hulpmiddelen voor het inspecteren en debuggen van crawls
  • Horizontaal schaalbare gedistribueerde crawler-backend

Dit vereenvoudigt het schrapen van zelfs geavanceerde JavaScript-webapps zonder Playwright-codering. Crawlee's crawler as a service is ideaal voor gebruikers die hun eigen scraperinfrastructuur niet willen beheren.

Ondersteunde apps zijn onder meer:

  • React- en Next.js-apps
  • Hoekige SPA's
  • Vue.js-pagina's
  • Webpack-sites
  • AJAX zware pagina's
  • PWA's en Electron-apps
  • Dynamische en responsieve ontwerpen

Door kant-en-klare ondersteuning te bieden voor scraping-uitdagingen zoals wachtvoorwaarden, geverifieerde sessies en dynamische inhoudswijzigingen, is Crawlee een aantrekkelijke keuze voor SPA-scraping zonder complexe scripts te schrijven.

Conclusie

Het scrapen van moderne single-page-applicaties vereist het emuleren van gebruikersinteracties en het wachten op asynchrone JavaScript-activiteit. Playwright biedt uitstekende mogelijkheden voor browserautomatisering om deze uitdagingen te overwinnen.

De belangrijkste strategieën die in deze gids worden behandeld, zijn onder meer:

  • Wachten tot de initiële inhoud en dynamische updates zijn geladen voordat deze worden uitgepakt
  • Luisteren naar DOM-wijzigingen om nieuwe inhoud te detecteren die wordt weergegeven
  • Het onderscheppen van REST API- en GraphQL-verzoeken om toegang te krijgen tot backend-gegevens
  • Emulatie van mobiele apparaten en beperking om responsieve ontwerpen te verwerken
  • Sessies authenticeren en cookies beheren om toegang te krijgen tot privégebruikersgegevens

Door deze patronen te volgen, kunt u onderhoudbare Playwright-scrapers ontwikkelen voor zelfs complexe SPA's die sterk afhankelijk zijn van JavaScript en API's aan de clientzijde.

Op grote schaal kan het gebruik van scraping API-services, headless browserfarms en gehoste crawlers efficiënter zijn dan het bouwen van uw eigen Playwright-infrastructuur.

Terwijl het schrijven van Playwright-scripts maximale flexibiliteit biedt, bieden tools zoals Crawlee een eenvoudiger kant-en-klare scraping-service voor SPA's zonder dat u zelf browserautomatiseringsscripts hoeft te coderen.

Ik hoop dat deze gids je een goed inzicht heeft gegeven in de technieken voor het schrapen van uitdagende apps met één pagina met behulp van Playwright. Laat het me weten als je nog vragen hebt!

Doe mee aan het gesprek

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd *