Playwright: Web Scraping & Testing

Mastera l'automazione del browser per il testing e lo scraping

Indice

Playwright è un potente framework moderno per l’automazione del browser che rivoluziona lo scraping web e i test end-to-end.

Sviluppato da Microsoft, fornisce un’API unificata per automatizzare i browser Chromium, Firefox e WebKit con un’affidabilità e una velocità senza precedenti.

playwright ui

Cosa è Playwright?

Playwright è un framework open source per l’automazione del browser che consente agli sviluppatori di scrivere test end-to-end affidabili e di costruire soluzioni avanzate per lo scraping web. A differenza degli strumenti tradizionali di automazione, Playwright è stato creato da zero per gestire le applicazioni web moderne con contenuti dinamici, applicazioni a singola pagina (SPA) e complessi framework JavaScript.

Il framework affronta il problema centrale che ha tormentato gli strumenti di automazione precedenti: l’instabilità. Playwright introduce meccanismi di auto-attesa che attendono automaticamente gli elementi per essere azionabili prima di eseguire le operazioni, eliminando la necessità di timeout arbitrari e istruzioni sleep che rendevano i test instabili.

Funzionalità principali

Supporto multi-browser: Playwright supporta tutti i principali motori di browser - Chromium (inclusi Chrome e Edge), Firefox e WebKit (Safari). Questo significa che puoi scrivere lo script di automazione una volta e eseguirlo su diversi browser senza modifiche, garantendo che le tue applicazioni web funzionino in modo coerente ovunque.

Auto-attesa: Una delle funzionalità più potenti di Playwright è il meccanismo di auto-attesa integrato. Prima di eseguire qualsiasi azione, Playwright attende automaticamente che gli elementi siano visibili, abilitati, stabili e non oscurati. Questo elimina le condizioni di gara e rende i test notevolmente più affidabili rispetto a strumenti come Selenium dove spesso sono necessari attese esplicite.

Intercezione della rete: Playwright consente di intercettare, modificare e simulare le richieste e le risposte di rete. Questo è estremamente utile per testare casi limite, simulare reti lente, bloccare risorse non necessarie durante lo scraping o simulare risposte API senza aver bisogno di un backend.

Emulazione mobile: Testa le applicazioni web mobili emulando diversi dispositivi mobili con dimensioni specifiche dello schermo, agenti utente e eventi di tocco. Playwright include descrittori di dispositivi per telefoni e tablet popolari.

Selezori potenti: Oltre ai selezionatori CSS e XPath, Playwright supporta selezionatori basati sul testo, selezionatori basati sui ruoli per i test di accessibilità e persino selezionatori sperimentali per i framework basati su componenti come React e Vue.

Installazione e configurazione

L’installazione di Playwright è semplice in diversi linguaggi di programmazione.

Installazione in Python

Per i progetti Python, Playwright può essere installato tramite pip e include sia API sincrone che asincrone. Se stai cercando un gestore più veloce e moderno dei pacchetti, dei progetti e degli ambienti Python, consulta la nostra guida su uv - Gestore di pacchetti, progetti e ambienti Python:

# Installa il pacchetto Playwright
pip install playwright

# Installa i browser (Chromium, Firefox, WebKit)
playwright install

# Per un solo browser specifico
playwright install chromium

Per un riferimento completo della sintassi Python e dei comandi comunemente utilizzati durante l’utilizzo di Playwright, consulta il nostro Foglio di riferimento Python.

Installazione in JavaScript/TypeScript

Per i progetti Node.js, installa Playwright tramite npm o yarn:

# Utilizzando npm
npm init playwright@latest

# Utilizzando yarn
yarn create playwright

# Installazione manuale
npm install -D @playwright/test
npx playwright install

Il comando npm init playwright fornisce un setup interattivo che configura il tuo progetto con test di esempio, file di configurazione e flusso di lavoro GitHub Actions.

Configurazione di base

Crea un file playwright.config.ts (TypeScript) o playwright.config.js (JavaScript):

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'] },
    },
  ],
});

Scraping web con Playwright

Playwright eccelle nello scraping web, soprattutto per siti web moderni con contenuti dinamici che le librerie tradizionali di scraping faticano a gestire.

Esempio di scraping di base

Ecco un esempio completo in Python che dimostra concetti di scraping fondamentali:

from playwright.sync_api import sync_playwright
import json

def scrape_website():
    with sync_playwright() as p:
        # Avvia il browser
        browser = p.chromium.launch(headless=True)
        
        # Crea un contesto per l'isolamento
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080},
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        )
        
        # Apri una nuova pagina
        page = context.new_page()
        
        # Naviga all'URL
        page.goto('https://example.com/products')
        
        # Attendi che il contenuto venga caricato
        page.wait_for_selector('.product-item')
        
        # Estrai i dati
        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
            })
        
        # Pulisci
        browser.close()
        
        return data

# Esegui lo scraper
results = scrape_website()
print(json.dumps(results, indent=2))

Gestione del contenuto dinamico

I siti web moderni caricano spesso il contenuto dinamicamente tramite JavaScript. Playwright gestisce questo in modo fluido:

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')
        
        # Scorri per caricare più contenuti
        for _ in range(5):
            await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
            await page.wait_for_timeout(2000)
        
        # Attendi che la rete sia inattiva
        await page.wait_for_load_state('networkidle')
        
        # Estrai tutti gli elementi caricati
        items = await page.query_selector_all('.item')
        
        await browser.close()

Conversione del contenuto estratto in Markdown

Dopo aver estratto il contenuto HTML con Playwright, spesso è necessario convertirlo in un formato più utilizzabile. Per guide complete sulla conversione da HTML a Markdown, consulta i nostri articoli su Conversione da HTML a Markdown con Python: Una guida completa che confronta 6 diverse librerie Python, e Conversione del contenuto HTML in Markdown utilizzando LLM e Ollama per la conversione potenziata dall’AI. Se stai lavorando con documenti Word invece, consulta la nostra guida su Conversione di documenti Word in Markdown.

Autenticazione e gestione delle sessioni

Quando lo scraping richiede l’autenticazione, Playwright rende semplice salvare e riutilizzare lo stato del browser:

def login_and_save_session():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()
        
        # Login
        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"]')
        
        # Attendi la navigazione dopo il login
        page.wait_for_url('**/dashboard')
        
        # Salva lo stato autenticato
        context.storage_state(path='auth_state.json')
        
        browser.close()

def scrape_with_saved_session():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        # Riutilizza lo stato di autenticazione salvato
        context = browser.new_context(storage_state='auth_state.json')
        page = context.new_page()
        
        # Già autenticato!
        page.goto('https://example.com/protected-data')
        # ... estrai il contenuto protetto
        
        browser.close()

Questo approccio è particolarmente utile quando si lavora con API o si costruiscono server MCP per l’integrazione con strumenti AI. Per una guida completa sull’implementazione dello scraping web nell’integrazione con strumenti AI, consulta il nostro articolo su Costruzione di server MCP in Python: WebSearch & Scrape.

Test end-to-end

L’uso principale di Playwright è la scrittura di test end-to-end robusti per le applicazioni web.

Scrivi il tuo primo test

Ecco un esempio completo di test in TypeScript:

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

test('l'utente può aggiungere un elemento al carrello', async ({ page }) => {
  // Naviga alla homepage
  await page.goto('https://example-shop.com');
  
  // Cerca un prodotto
  await page.fill('[data-testid="search-input"]', 'laptop');
  await page.press('[data-testid="search-input"]', 'Enter');
  
  // Attendi i risultati della ricerca
  await expect(page.locator('.product-card')).toBeVisible();
  
  // Clicca sul primo prodotto
  await page.locator('.product-card').first().click();
  
  // Verifica che la pagina del prodotto sia caricata
  await expect(page).toHaveURL(/\/product\/.+/);
  
  // Aggiungi al carrello
  await page.click('[data-testid="add-to-cart"]');
  
  // Verifica che il carrello sia aggiornato
  const cartCount = page.locator('[data-testid="cart-count"]');
  await expect(cartCount).toHaveText('1');
});

Modello di pagina

Per i test suite più grandi, utilizza il modello di pagina per migliorare la manutenibilità:

// 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 con credenziali non valide mostra un errore', 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('Credenziali non valide');
});

Funzionalità avanzate

Codegen - Generazione automatica dei test

Lo strumento Codegen di Playwright genera i test registrando le tue interazioni con una pagina web:

# Apri Codegen
playwright codegen example.com

# Con un browser specifico
playwright codegen --browser firefox example.com

# Con uno stato di autenticazione salvato
playwright codegen --load-storage=auth.json example.com

Mentre interagisci con la pagina, Codegen genera il codice in tempo reale. Questo è estremamente utile per prototipare rapidamente i test o imparare la sintassi dei selezionatori di Playwright.

Trace Viewer per il debug

Quando i test falliscono, capire perché può essere difficile. Il Trace Viewer di Playwright fornisce una visualizzazione cronologica dell’esecuzione del test:

// Abilita il tracciamento nella configurazione
use: {
  trace: 'on-first-retry',
}

Dopo che un test fallisce e si riprova, visualizza il tracciamento:

playwright show-trace trace.zip

Il Trace Viewer mostra screenshot in ogni azione, attività di rete, log del console e snapshot del DOM, rendendo il debug semplice.

Intercezione e simulazione della rete

Intercepta e modifica il traffico di rete per testare casi limite:

def test_with_mocked_api():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        
        # Simula una risposta API
        def handle_route(route):
            if 'api/products' in route.request.url:
                route.fulfill(
                    status=200,
                    body=json.dumps({
                        'products': [
                            {'id': 1, 'name': 'Prodotto di test', 'price': 99.99}
                        ]
                    })
                )
            else:
                route.continue_()
        
        page.route('**/*', handle_route)
        
        page.goto('https://example.com')
        # La pagina ora utilizza i dati simulati
        
        browser.close()

Test mobile

Testa i tuoi design responsivi su diversi dispositivi:

from playwright.sync_api import sync_playwright

def test_mobile():
    with sync_playwright() as p:
        # Usa il descrittore del dispositivo
        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')
        
        # Interagisci come un utente mobile
        page.locator('#mobile-menu-button').click()
        
        browser.close()

Linee guida

Per lo scraping web

  1. Utilizza la modalità headless in produzione: L’uso del browser headless è più veloce e utilizza risorse minori
  2. Implementa il rate limiting: Rispetta i siti web con ritardi tra le richieste
  3. Gestisci gli errori in modo gentile: Si verificano problemi di rete, timeout e modifiche ai selezionatori
  4. Ruota gli user agent: Evita la rilevazione variando le impronte del browser
  5. Rispetta il robots.txt: Controlla e segui le politiche di scraping del sito web
  6. Utilizza l’isolamento del contesto: Crea contesti del browser separati per lo scraping parallelo

Quando si converte il contenuto estratto in formato markdown, considera l’uso di strumenti basati su LLM o librerie Python specializzate per la conversione da HTML a markdown per un output più pulito.

Per i test

  1. Utilizza gli attributi data-testid: Più stabili rispetto alle classi CSS che cambiano frequentemente
  2. Evita attese hard: Utilizza i meccanismi di attesa integrati di Playwright invece di sleep()
  3. Mantieni i test indipendenti: Ogni test deve poter essere eseguito in isolamento
  4. Utilizza i fixtures: Condividi il codice di setup tra i test in modo efficiente
  5. Esegui i test in parallelo: Sfrutta i thread worker di Playwright per la velocità
  6. Registra i tracciamenti in caso di fallimento: Abilita la registrazione dei tracciamenti per un debug più facile

Ottimizzazione delle prestazioni

# Disattiva le risorse non necessarie
def fast_scraping():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context()
        page = context.new_page()
        
        # Blocca immagini e fogli di stile per accelerare lo scraping
        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()

Confronto tra Playwright e alternative

Playwright vs Selenium

Vantaggi di Playwright:

  • L’attesa automatica integrata elimina i test instabili
  • Esecuzione più rapida grazie all’architettura moderna
  • Migliore intercettazione e simulazione della rete
  • Strumenti di debug superiori (Trace Viewer)
  • API più semplice con meno boilerplate
  • Supporto multi-browser con un’unica installazione

Vantaggi di Selenium:

  • Ecosistema più maturo con una comunità estesa
  • Supporta più linguaggi di programmazione
  • Maggiore compatibilità con browser, inclusi i vecchi

Playwright vs Puppeteer

Vantaggi di Playwright:

  • Supporto cross-browser vero (Firefox, WebKit, Chromium)
  • API più potente basata sulle lezioni di Puppeteer
  • Strumenti di debug più potenti
  • Supporto attivo da parte di Microsoft

Vantaggi di Puppeteer:

  • Dimensioni leggermente più piccole
  • Esperti nel protocollo Chrome DevTools

Per la maggior parte dei nuovi progetti, Playwright è la scelta consigliata grazie alla sua architettura moderna e all’ampio insieme di funzionalità. Se stai lavorando con Go invece che con Python o JavaScript e hai bisogno di capacità di scraping, consulta la nostra guida su Alternative a Beautiful Soup per Go per strumenti di scraping comparabili nell’ecosistema Go.

Caso d’uso comuni

Estrazione di dati per applicazioni AI/LLM

Playwright è eccellente per raccogliere dati di addestramento o creare capacità di ricerca web per modelli AI. Quando si costruiscono server MCP (Model Context Protocol), Playwright può gestire il componente di scraping web mentre gli LLM elaborano il contenuto estratto.

Test automatizzati in CI/CD

Integra i test di Playwright nel tuo pipeline di integrazione continua:

# .github/workflows/playwright.yml
name: Test di Playwright
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  test:
    timeout-minuti: 60
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: 18
    - name: Installa le dipendenze
      run: npm ci
    - name: Installa i browser di Playwright
      run: npx playwright install --with-deps
    - name: Esegui i test di Playwright
      run: npx playwright test
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: rapporto-playwright
        path: rapporto-playwright/
        retention-days: 30

Monitoraggio del sito web

Monitora i tuoi siti web in produzione per l’uptime e la funzionalità:

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)
            
            # Controlla elementi critici
            assert page.is_visible('.header')
            assert page.is_visible('#main-content')
            
            print("✓ Il sito è in salute")
        except Exception as e:
            print(f"✗ Rilevato problema nel sito: {e}")
            # Invia un avviso
        finally:
            browser.close()

# Esegui ogni 5 minuti
schedule.every(5).minutes.do(monitor_website)

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

Risoluzione dei problemi comuni

Problemi di installazione del browser

Se i browser falliscono nel download:

# Imposta una posizione di download personalizzata
PLAYWRIGHT_BROWSERS_PATH=/custom/path playwright install

# Pulisci la cache e reinstalla
playwright uninstall
playwright install

Errori di timeout

Aumenta i timeout per reti lente o pagine complesse:

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

Selettore non trovato

Utilizza l’Inspector di Playwright per identificare i selezionatori corretti:

PWDEBUG=1 pytest test_file.py

Questo apre l’inspector dove puoi passare il mouse sugli elementi per vedere i loro selezionatori.

Conclusione

Playwright rappresenta l’avanguardia della tecnologia di automazione del browser, combinando funzionalità potenti con un’esperienza eccellente per gli sviluppatori. Che tu stia costruendo una pipeline di scraping web, implementando una copertura di test completa o creando flussi di lavoro automatizzati, Playwright fornisce gli strumenti e l’affidabilità necessari.

I meccanismi di auto-attesa eliminano i test instabili, il supporto multi-browser garantisce che le tue applicazioni funzionino ovunque, e gli strumenti di debug potenti rendono il troubleshooting semplice. Man mano che le applicazioni web diventano sempre più complesse, l’architettura moderna di Playwright e lo sviluppo attivo lo rendono una scelta eccellente per ogni esigenza di automazione del browser.

Per gli sviluppatori Python che lavorano su pipeline di dati o progetti di scraping web, Playwright si integra in modo impeccabile con i gestori moderni di pacchetti e funziona in modo eccellente insieme a pandas, requests e ad altri strumenti di data science. La capacità di estrarre dati strutturati da siti web moderni complessi lo rende inestimabile per applicazioni AI, progetti di ricerca e intelligence aziendale. Quando combinato con strumenti di conversione da HTML a Markdown e con un’adeguata elaborazione del contenuto, Playwright diventa una soluzione completa per l’estrazione, la trasformazione e l’utilizzo di dati web su larga scala.

Altri riferimenti