Playwright: Webbscraping & testning

Behärska webbläsarautomatisering för testning och skrapning

Sidinnehåll

Playwright är en kraftfull, modern ramverk för webbläsarautomatisering som revolutionerar webbscraping och slutna test.

Utvecklad av Microsoft, ger den en enhetlig API för att automatisera webbläsare som Chromium (inklusive Chrome och Edge), Firefox och WebKit (Safari) med ovanligt hög pålitlighet och hastighet.

playwright ui

Vad är Playwright?

Playwright är ett öppen källkod ramverk för webbläsarautomatisering som möjliggör för utvecklare att skriva pålitliga slutna tester och bygga avancerade lösningar för webbscraping. Till skillnad från traditionella automatiseringsverktyg är Playwright byggd från grunden för att hantera moderna webbapplikationer med dynamiskt innehåll, en-sida-applikationer (SPAs) och komplexa JavaScript-ramverk.

Ramverket löser det centrala problemet som tidigare automatiseringsverktyg hade: osäkerhet. Playwright introducerar mekanismer för automatisk väntande som automatiskt väntar på att elementen blir tillgängliga innan åtgärder utförs, vilket eliminerar behovet av godtyckliga tidsgränser och väntesatser som gjorde test oberoende.

Viktiga funktioner

Korswebbläsarsupport: Playwright stöder alla huvudsakliga webbläsarmotorer – Chromium (inklusive Chrome och Edge), Firefox och WebKit (Safari). Detta innebär att du kan skriva din automatiseringskod en gång och köra den i olika webbläsare utan ändringar, säkerställande att dina webbapplikationer fungerar konsekvent överallt.

Automatisk väntande: En av Playwrights mest kraftfulla funktioner är dess inbyggda mekanism för automatisk väntande. Innan någon åtgärd utförs väntar Playwright automatiskt på att elementen blir synliga, aktiverade, stabila och inte dolda. Detta eliminerar race conditions och gör test betydligt mer pålitliga jämfört med verktyg som Selenium där explicita väntanden ofta är nödvändiga.

Nätverksinterceptering: Playwright möjliggör att du kan interceptera, modifiera och mocka nätverksförfrågningar och svar. Detta är värdefullt för att testa gränsfall, simulera långsamma nätverk, blockera onödiga resurser under scraping eller mocka API-svar utan att behöva en bakända.

Mobilanvändning: Testa mobilwebbapplikationer genom att emulera olika mobilenheter med specifika viewportstorlekar, användaragent och touchhändelser. Playwright innehåller enhetsbeskrivningar för populära telefoner och tabletter.

Kraftfulla selektorer: Utöver CSS- och XPath-selektorer stöder Playwright textselektorer, selektorer baserade på roll för tillgänglighets-testning samt experimentella selektorer för React och Vue för komponentbaserade ramverk.

Installation och konfiguration

Att installera Playwright är enkelt i olika programmeringsspråk.

Python installation

För Pythonprojekt kan Playwright installeras via pip och innehåller både synkrona och asynkrona API:er. Om du söker efter en snabbare, modernare Python-pakethanterare, se vår guide om uv - Python-paket, projekt- och miljöhanterare:

# Installera Playwright-paket
pip install playwright

# Installera webbläsare (Chromium, Firefox, WebKit)
playwright install

# För en specifik webbläsare
playwright install chromium

För en omfattande referens av Python-syntax och vanligt använda kommandon vid arbete med Playwright, se vår Python Cheat Sheet.

JavaScript/TypeScript installation

För Node.js-projekt installera Playwright via npm eller yarn:

# Med npm
npm init playwright@latest

# Med yarn
yarn create playwright

# Manuell installation
npm install -D @playwright/test
npx playwright install

Kommandot npm init playwright ger en interaktiv konfiguration som konfigurerar ditt projekt med exempeltest, konfigurationsfiler och GitHub Actions-arbetsflöde.

Grundläggande konfiguration

Skapa en playwright.config.ts (TypeScript) eller playwright.config.js (JavaScript) fil:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  timeout: 30000,
  retries: 2,
  workers: 4,
  use: {
    headless: true,
    viewport: { width: 1280, height: 720 },
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
});

Webbscraping med Playwright

Playwright är utmärkt för webbscraping, särskilt för moderna webbplatser med dynamiskt innehåll som traditionella scraping-bibliotek har svårt att hantera.

Grundläggande exempel på scraping

Här är ett omfattande Python-exempel som visar kärnkoncepten för scraping:

from playwright.sync_api import sync_playwright
import json

def scrape_website():
    with sync_playwright() as p:
        # Starta webbläsare
        browser = p.chromium.launch(headless=True)
        
        # Skapa kontext för isolering
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080},
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        )
        
        # Öppna ny sida
        page = context.new_page()
        
        # Navigera till URL
        page.goto('https://example.com/products')
        
        # Vänta på innehåll att laddas
        page.wait_for_selector('.product-item')
        
        # Extrahera data
        products = page.query_selector_all('.product-item')
        
        data = []
        for product in products:
            title = product.query_selector('h2').inner_text()
            price = product.query_selector('.price').inner_text()
            url = product.query_selector('a').get_attribute('href')
            
            data.append({
                'title': title,
                'price': price,
                'url': url
            })
        
        # Rensa upp
        browser.close()
        
        return data

# Kör scraper
results = scrape_website()
print(json.dumps(results, indent=2))

Hantering av dynamiskt innehåll

Moderna webbplatser laddar ofta innehåll dynamiskt via JavaScript. Playwright hanterar detta smidigt:

async def scrape_dynamic_content():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        
        await page.goto('https://example.com/infinite-scroll')
        
        # Rulla för att ladda mer innehåll
        for _ in range(5):
            await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
            await page.wait_for_timeout(2000)
        
        # Vänta på nätverket att bli stilla
        await page.wait_for_load_state('networkidle')
        
        # Extrahera alla laddade objekt
        items = await page.query_selector_all('.item')
        
        await browser.close()

Konvertera skrapad innehåll till Markdown

Efter att ha extraherat HTML-innehåll med Playwright behöver du ofta konvertera det till en mer användbar form. För omfattande guider om att konvertera HTML till Markdown, se våra artiklar om Konvertera HTML till Markdown med Python: En omfattande guide som jämför 6 olika Python-bibliotek, och Konvertera HTML-innehåll till Markdown med LLM och Ollama för AI-baserad konvertering. Om du arbetar med Word-dokument istället, se vår guide om Konvertera Word-dokument till Markdown.

Autentisering och sessionshantering

När scraping kräver autentisering gör Playwright det enkelt att spara och återanvända webbläsarstatus:

def login_and_save_session():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()
        
        # Logga in
        page.goto('https://example.com/login')
        page.fill('input[name="username"]', 'your_username')
        page.fill('input[name="password"]', 'your_password')
        page.click('button[type="submit"]')
        
        # Vänta på navigering efter inloggning
        page.wait_for_url('**/dashboard')
        
        # Spara autentiserad status
        context.storage_state(path='auth_state.json')
        
        browser.close()

def scrape_with_saved_session():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        # Använd sparad autentisering
        context = browser.new_context(storage_state='auth_state.json')
        page = context.new_page()
        
        # Redan autentiserad!
        page.goto('https://example.com/protected-data')
        # ... skrapa skyddat innehåll
        
        browser.close()

Detta är särskilt användbart när man arbetar med API:er eller bygger MCP-server för AI-integrering. För en fullständig guide om att implementera webbscraping i AI-verktyg, se vår artikel om Bygg MCP-server i Python: Webbsökning & Skrapa.

Slutna test

Playwrights primära användningsområde är att skriva robusta slutna tester för webbapplikationer.

Skriv ditt första test

Här är ett komplett testexempel i TypeScript:

import { test, expect } from '@playwright/test';

test('användare kan lägga till artikel i kundvagn', async ({ page }) => {
  // Navigera till startsidan
  await page.goto('https://example-shop.com');
  
  // Sök efter produkt
  await page.fill('[data-testid="search-input"]', 'laptop');
  await page.press('[data-testid="search-input"]', 'Enter');
  
  // Vänta på sökresultat
  await expect(page.locator('.product-card')).toBeVisible();
  
  // Klicka på första produkten
  await page.locator('.product-card').first().click();
  
  // Verifiera att produktsidan laddats
  await expect(page).toHaveURL(/\/product\/.+/);
  
  // Lägg till i kundvagn
  await page.click('[data-testid="add-to-cart"]');
  
  // Verifiera att kundvagnen uppdaterats
  const cartCount = page.locator('[data-testid="cart-count"]');
  await expect(cartCount).toHaveText('1');
});

Sidobjektmodell

För större testuppsättningar, använd sidobjektmodellmönstret för att förbättra underhållbarhet:

// pages/LoginPage.ts
export class LoginPage {
  constructor(private page: Page) {}
  
  async navigate() {
    await this.page.goto('/login');
  }
  
  async login(username: string, password: string) {
    await this.page.fill('[name="username"]', username);
    await this.page.fill('[name="password"]', password);
    await this.page.click('button[type="submit"]');
  }
  
  async getErrorMessage() {
    return await this.page.locator('.error-message').textContent();
  }
}

// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';

test('login med ogiltiga uppgifter visar fel', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.navigate();
  await loginPage.login('invalid@email.com', 'wrongpass');
  
  const error = await loginPage.getErrorMessage();
  expect(error).toContain('Ogiltiga uppgifter');
});

Avancerade funktioner

Codegen - Automatisk testgenerering

Playwrights Codegen-verktyg genererar tester genom att registrera interaktionerna med en webbsida:

# Öppna Codegen
playwright codegen example.com

# Med specifik webbläsare
playwright codegen --browser firefox example.com

# Med sparad autentisering
playwright codegen --load-storage=auth.json example.com

När du interagerar med sidan genererar Codegen kod i realtid. Detta är mycket användbart för att snabbt prototypera tester eller lära dig Playwrights selektor syntax.

Trace Viewer för felsökning

När tester misslyckas kan det vara svårt att förstå varför. Playwrights Trace Viewer ger en tidslinjevy av testutförandet:

// Aktivera spårning i konfiguration
use: {
  trace: 'on-first-retry',
}

Efter att en test misslyckats och försöker igen, visa spåret:

playwright show-trace trace.zip

Trace Viewer visar skärmbilder vid varje handling, nätverksaktivitet, konsolloggar och DOM-snapshot, vilket gör felsökning enklare.

Nätverksinterceptering och mockning

Interceptera och modifiera nätverksförfrågningar för att testa gränsfall:

def test_with_mocked_api():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        
        # Mocka API-svar
        def handle_route(route):
            if 'api/products' in route.request.url:
                route.fulfill(
                    status=200,
                    body=json.dumps({
                        'products': [
                            {'id': 1, 'name': 'Test Produkt', 'price': 99.99}
                        ]
                    })
                )
            else:
                route.continue_()
        
        page.route('**/*', handle_route)
        
        page.goto('https://example.com')
        # Sidan använder nu mockade data
        
        browser.close()

Mobiltestning

Testa dina responsiva design på olika enheter:

from playwright.sync_api import sync_playwright

def test_mobile():
    with sync_playwright() as p:
        # Använd enhetsbeskrivning
        iphone_13 = p.devices['iPhone 13']
        
        browser = p.webkit.launch()
        context = browser.new_context(**iphone_13)
        page = context.new_page()
        
        page.goto('https://example.com')
        
        # Interagera som mobilanvändare
        page.locator('#mobile-menu-button').click()
        
        browser.close()

Bästa praxis

För webbscraping

  1. Använd headlessläge i produktion: Headlessbrowsing är snabbare och använder färre resurser
  2. Implementera hastighetsbegränsning: Respektera målwebbplatser med förseningar mellan förfrågningar
  3. Hantera fel på ett snyftigt sätt: Nätverksproblem, tidsgränser och selektorändringar inträffar
  4. Byt användaragent: Undvik detektering genom att variera webbläsarfingeravtryck
  5. Respektera robots.txt: Kontrollera och följ webbscrapningspolicyer
  6. Använd kontextisolation: Skapa separata webbläsarkontexter för parallell scraping

När du konverterar skrapat innehåll till markdownformat, överväg att använda LLM-baserade konverteringsverktyg eller Python-bibliotek som är specialiserade för HTML-till-Markdown-konvertering för renare utdata.

För testning

  1. Använd data-testid-attribut: Mer stabila än CSS-klasser som ofta ändras
  2. Undvik hård vänta: Använd Playwrights inbyggda väntemekanismer istället för sleep()
  3. Håll testen oberoende: Varje test ska kunna köras i isolering
  4. Använd fixtures: Dela uppställningskod mellan tester effektivt
  5. Kör tester parallellt: Utnyttja Playwrights workertrådar för hastighet
  6. Spela in spår vid misslyckande: Aktivera spårinspelning för enklare felsökning

Prestandaoptimering

# Inaktivera onödiga resurser
def fast_scraping():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context()
        page = context.new_page()
        
        # Blockera bilder och stylesheets för att snabbare skrapa
        async def block_resources(route):
            if route.request.resource_type in ['image', 'stylesheet', 'font']:
                await route.abort()
            else:
                await route.continue_()
        
        page.route('**/*', block_resources)
        page.goto('https://example.com')
        
        browser.close()

Jämförelse mellan Playwright och alternativ

Playwright vs Selenium

Playwrights fördelar:

  • Inbyggd automatisk väntande eliminierar osäkra tester
  • Snabbare utförande på grund av modern arkitektur
  • Bättre nätverksinterceptering och mockning
  • Bättre felsökningsverktyg (Trace Viewer)
  • Enklare API med mindre boilerplate
  • Många webbläsare med en installation

Seleniums fördelar:

  • Mer mognad i ekosystemet med omfattande community
  • Stöd för fler programmeringsspråk
  • Bättre webbläsarkompatibilitet inklusive äldre versioner

Playwright vs Puppeteer

Playwrights fördelar:

  • Riktig korswebbläsarsupport (Firefox, WebKit, Chromium)
  • Bättre API-design baserat på Puppeteer-undervisningar
  • Mer kraftfulla felsökningsverktyg
  • Microsofts stöd och aktiv utveckling

Puppeteers fördelar:

  • Lättare storlek
  • Expertis i Chrome DevTools Protocol

För de flesta nya projekt är Playwright det rekommenderade valet på grund av dess moderna arkitektur och omfattande funktionssätt. Om du arbetar med Go istället för Python eller JavaScript och behöver webbscrapingfunktioner, se vår guide om Beautiful Soup Alternativ för Go för jämförbara scrapingsverktyg i Go-ekosystemet.

Vanliga användningsområden

Dataextraktion för AI/LLM-program

Playwright är utmärkt för att samla träningsdata eller skapa webbsökningssystem för AI-modeller. När du bygger MCP (Model Context Protocol)-servrar kan Playwright hantera webbscrapingskomponenten medan LLM:er bearbetar den extraherade innehållet.

Automatiserade tester i CI/CD

Integrera Playwright-test i din kontinuerliga integrationspipeline:

# .github/workflows/playwright.yml
name: Playwright Tests
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: 18
    - name: Installera beroenden
      run: npm ci
    - name: Installera Playwright-webbläsare
      run: npx playwright install --with-deps
    - name: Kör Playwright-test
      run: npx playwright test
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

Webbsidövervakning

Övervaka dina produktionswebbsidor för upptid och funktion:

import schedule
import time

def monitor_website():
    with sync_playwright() as p:
        try:
            browser = p.chromium.launch()
            page = browser.new_page()
            page.goto('https://your-site.com', timeout=30000)
            
            # Kontrollera kritiska element
            assert page.is_visible('.header')
            assert page.is_visible('#main-content')
            
            print("✓ Webbsidan är hälsosam")
        except Exception as e:
            print(f"✗ Problem upptäckt: {e}")
            # Skicka varning
        finally:
            browser.close()

# Kör varje 5 minuter
schedule.every(5).minutes.do(monitor_website)

while True:
    schedule.run_pending()
    time.sleep(1)

Felsökning av vanliga problem

Problem med installation av webbläsare

Om webbläsare inte lyckas laddas ner:

# Ställ in en anpassad nedladdningsplats
PLAYWRIGHT_BROWSERS_PATH=/custom/path playwright install

# Rensa cache och installera om
playwright uninstall
playwright install

Tidsgränsfel

Öka tidsgränser för långsamma nätverk eller komplexa sidor:

page.goto('https://slow-site.com', timeout=60000)  # 60 sekunder
page.wait_for_selector('.element', timeout=30000)  # 30 sekunder

Selektor hittas inte

Använd Playwright-inspektorn för att identifiera korrekt selektor:

PWDEBUG=1 pytest test_file.py

Detta öppnar inspektorn där du kan hovra över element för att se deras selektorer.

Slutsats

Playwright representerar kantlinjen av webbläsarautomatiserings teknologi, kombinerar kraftfulla funktioner med utmärkt utvecklare upplevelse. Oavsett om du bygger en webbscrapingpipeline, implementerar omfattande testcoverage eller skapar automatiserade arbetsflöden, ger Playwright de verktyg och pålitlighet du behöver.

Dess mekanismer för automatisk väntande eliminierar osäkra tester, korswebbläsarsupport säkerställer att dina applikationer fungerar överallt och kraftfulla felsökningsverktyg gör felsökning enkel. Medan webbapplikationer fortsätter att växa i komplexitet gör Playwrights moderna arkitektur och aktiv utveckling det till ett utmärkt val för alla webbläsarautomatiseringsbehov.

För Python-utvecklare som arbetar med datapipelines eller webbscrapingprojekt integreras Playwright smidigt med moderna pakethanterare och fungerar utmärkt tillsammans med pandas, requests och andra datavetenskapstool. Möjligheten att extrahera strukturerat data från komplexa moderna webbsidor gör det värdefullt för AI-program, forskningsprojekt och affärsintelligens. När kombinerat med HTML-till-Markdown-konverteringsverktyg och korrekt innehållsbehandling blir Playwright en komplett lösning för att extrahera, omvandla och använda webbdata i stora skala.

Några användbara länkar

Övriga referenser