Playwright : Extraction de données web & Tests

Maîtrisez l'automatisation des navigateurs pour les tests et le scraping

Sommaire

Playwright est un cadre d’automatisation de navigateur puissant et moderne qui révolutionne le scraping web et les tests de bout en bout.

Développé par Microsoft, il fournit une API unifiée pour automatiser les navigateurs Chromium, Firefox et WebKit avec une fiabilité et une vitesse sans précédent.

playwright ui

Qu’est-ce que Playwright ?

Playwright est un cadre d’automatisation de navigateur open-source qui permet aux développeurs d’écrire des tests de bout en bout fiables et de construire des solutions de scraping web sophistiquées. Contrairement aux outils d’automatisation traditionnels, Playwright a été conçu dès le départ pour gérer les applications web modernes avec du contenu dynamique, les applications monopage (SPA) et les frameworks JavaScript complexes.

Le cadre résout le problème central qui a plagé les outils d’automatisation précédents : la fiabilité. Playwright introduit des mécanismes d’attente automatique qui attendent automatiquement que les éléments soient actionnables avant d’effectuer des opérations, éliminant ainsi le besoin de délais d’attente arbitraires et d’instructions de sommeil qui rendaient les tests peu fiables.

Fonctionnalités clés

Prise en charge multi-navigateurs : Playwright prend en charge tous les moteurs de navigateurs principaux - Chromium (y compris Chrome et Edge), Firefox et WebKit (Safari). Cela signifie que vous pouvez écrire votre script d’automatisation une fois et l’exécuter sur différents navigateurs sans modification, garantissant que vos applications web fonctionnent de manière cohérente partout.

Attente automatique : L’une des fonctionnalités les plus puissantes de Playwright est son mécanisme d’attente automatique intégré. Avant d’effectuer toute action, Playwright attend automatiquement que les éléments soient visibles, activés, stables et non obscurcis. Cela élimine les conditions de course et rend les tests considérablement plus fiables par rapport aux outils comme Selenium où des attentes explicites sont souvent nécessaires.

Interception du réseau : Playwright permet d’intercepter, de modifier et de simuler les requêtes et réponses réseau. Cela est inestimable pour tester des cas limites, simuler des réseaux lents, bloquer des ressources inutiles lors du scraping, ou simuler des réponses d’API sans avoir besoin d’un backend.

Émulation mobile : Testez les applications web mobiles en émulant divers appareils mobiles avec des tailles de vue spécifiques, des agents utilisateurs et des événements tactiles. Playwright inclut des descripteurs d’appareils pour les téléphones et tablettes populaires.

Sélecteurs puissants : Au-delà des sélecteurs CSS et XPath, Playwright prend en charge les sélecteurs de texte, les sélecteurs basés sur les rôles pour les tests d’accessibilité, et même les sélecteurs expérimentaux React et Vue pour les frameworks basés sur les composants.

Installation et configuration

La configuration de Playwright est simple pour différents langages de programmation.

Installation Python

Pour les projets Python, Playwright peut être installé via pip et inclut des API à la fois synchrones et asynchrones. Si vous cherchez un gestionnaire de paquets Python plus rapide et plus moderne, consultez notre guide sur uv - Gestionnaire de paquets, projets et environnements Python:

# Installer le package Playwright
pip install playwright

# Installer les navigateurs (Chromium, Firefox, WebKit)
playwright install

# Pour un navigateur spécifique uniquement
playwright install chromium

Pour une référence complète de la syntaxe Python et des commandes couramment utilisées lors de la travail avec Playwright, consultez notre Fiche de triche Python.

Installation JavaScript/TypeScript

Pour les projets Node.js, installez Playwright via npm ou yarn :

# Utilisation de npm
npm init playwright@latest

# Utilisation de yarn
yarn create playwright

# Installation manuelle
npm install -D @playwright/test
npx playwright install

La commande npm init playwright fournit une configuration interactive qui configure votre projet avec des tests d’exemple, des fichiers de configuration et des workflows GitHub Actions.

Configuration de base

Créez un fichier playwright.config.ts (TypeScript) ou 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 avec Playwright

Playwright excelle dans le scraping web, surtout pour les sites web modernes avec du contenu dynamique que les bibliothèques de scraping traditionnelles ont du mal à gérer.

Exemple de scraping de base

Voici un exemple complet en Python démontrant les concepts de scraping de base :

from playwright.sync_api import sync_playwright
import json

def scrape_website():
    with sync_playwright() as p:
        # Lancer le navigateur
        browser = p.chromium.launch(headless=True)

        # Créer un contexte pour l'isolement
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080},
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        )

        # Ouvrir une nouvelle page
        page = context.new_page()

        # Naviguer vers l'URL
        page.goto('https://example.com/products')

        # Attendre que le contenu se charge
        page.wait_for_selector('.product-item')

        # Extraire les données
        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
            })

        # Nettoyer
        browser.close()

        return data

# Exécuter le scraper
results = scrape_website()
print(json.dumps(results, indent=2))

Gestion du contenu dynamique

Les sites web modernes chargent souvent du contenu dynamiquement via JavaScript. Playwright gère cela de manière transparente :

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')

        # Faire défiler pour charger plus de contenu
        for _ in range(5):
            await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
            await page.wait_for_timeout(2000)

        # Attendre que le réseau soit inactif
        await page.wait_for_load_state('networkidle')

        # Extraire tous les éléments chargés
        items = await page.query_selector_all('.item')

        await browser.close()

Conversion du contenu scrapé en Markdown

Après avoir extrait le contenu HTML avec Playwright, vous avez souvent besoin de le convertir en un format plus utilisable. Pour des guides complets sur la conversion de HTML en Markdown, consultez nos articles sur Convertir HTML en Markdown avec Python : Un guide complet qui compare 6 bibliothèques Python différentes, et Convertir le contenu HTML en Markdown en utilisant LLM et Ollama pour la conversion alimentée par l’IA. Si vous travaillez avec des documents Word à la place, consultez notre guide sur Convertir les documents Word en Markdown.

Authentification et gestion de session

Lorsque le scraping nécessite une authentification, Playwright facilite la sauvegarde et la réutilisation de l’état du navigateur :

def login_and_save_session():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()

        # Connexion
        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"]')

        # Attendre la navigation après la connexion
        page.wait_for_url('**/dashboard')

        # Sauvegarder l'état authentifié
        context.storage_state(path='auth_state.json')

        browser.close()

def scrape_with_saved_session():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        # Réutiliser l'état d'authentification sauvegardé
        context = browser.new_context(storage_state='auth_state.json')
        page = context.new_page()

        # Déjà authentifié !
        page.goto('https://example.com/protected-data')
        # ... scraper le contenu protégé

        browser.close()

Cette approche est particulièrement utile lors de la travail avec des APIs ou la construction de serveurs MCP pour des intégrations d’IA. Pour un guide complet sur la mise en œuvre du scraping web dans l’intégration d’outils d’IA, consultez notre article sur Construction de serveurs MCP en Python : WebSearch & Scrape.

Tests de bout en bout

L’utilisation principale de Playwright est l’écriture de tests de bout en bout robustes pour les applications web.

Écrire votre premier test

Voici un exemple complet de test en TypeScript :

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

test('un utilisateur peut ajouter un article au panier', async ({ page }) => {
  // Naviguer vers la page d'accueil
  await page.goto('https://example-shop.com');

  // Rechercher un produit
  await page.fill('[data-testid="search-input"]', 'ordinateur portable');
  await page.press('[data-testid="search-input"]', 'Enter');

  // Attendre les résultats de recherche
  await expect(page.locator('.product-card')).toBeVisible();

  // Cliquer sur le premier produit
  await page.locator('.product-card').first().click();

  // Vérifier que la page du produit est chargée
  await expect(page).toHaveURL(/\/product\/.+/);

  // Ajouter au panier
  await page.click('[data-testid="add-to-cart"]');

  // Vérifier que le panier est mis à jour
  const cartCount = page.locator('[data-testid="cart-count"]');
  await expect(cartCount).toHaveText('1');
});

Modèle Page Object

Pour des suites de tests plus importantes, utilisez le modèle Page Object pour améliorer la maintenabilité :

// 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('la connexion avec des identifiants invalides affiche une erreur', 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('Identifiants invalides');
});

Fonctionnalités avancées

Codegen - Génération automatique de tests

L’outil Codegen de Playwright génère des tests en enregistrant vos interactions avec une page web :

# Ouvrir Codegen
playwright codegen example.com

# Avec un navigateur spécifique
playwright codegen --browser firefox example.com

# Avec un état d'authentification enregistré
playwright codegen --load-storage=auth.json example.com

Au fur et à mesure que vous interagissez avec la page, Codegen génère du code en temps réel. Cela est extrêmement utile pour prototyper rapidement des tests ou apprendre la syntaxe des sélecteurs de Playwright.

Visionneuse de traces pour le débogage

Lorsque les tests échouent, comprendre pourquoi peut être difficile. La Visionneuse de traces de Playwright fournit une vue chronologique de l’exécution de votre test :

// Activer la traçabilité dans la configuration
use: {
  trace: 'on-first-retry',
}

Après qu’un test échoue et soit relancé, consultez la trace :

playwright show-trace trace.zip

La Visionneuse de traces montre des captures d’écran à chaque action, l’activité réseau, les journaux de console et les instantanés DOM, ce qui facilite le débogage.

Interception et simulation du réseau

Interceptez et modifiez le trafic réseau pour tester des cas limites :

def test_with_mocked_api():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()

        # Simuler la réponse API
        def handle_route(route):
            if 'api/products' in route.request.url:
                route.fulfill(
                    status=200,
                    body=json.dumps({
                        'products': [
                            {'id': 1, 'name': 'Produit de test', 'price': 99.99}
                        ]
                    })
                )
            else:
                route.continue_()

        page.route('**/*', handle_route)

        page.goto('https://example.com')
        # La page utilise maintenant des données simulées

        browser.close()

Tests mobiles

Testez vos conceptions réactives sur divers appareils :

from playwright.sync_api import sync_playwright

def test_mobile():
    with sync_playwright() as p:
        # Utiliser le descripteur de périphérique
        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')

        # Interagir en tant qu'utilisateur mobile
        page.locator('#mobile-menu-button').click()

        browser.close()

Bonnes pratiques

Pour le scraping web

  1. Utilisez le mode sans tête en production : Le mode sans tête est plus rapide et utilise moins de ressources
  2. Mettez en place une limitation de débit : Respectez les sites cibles avec des délais entre les requêtes
  3. Gérez les erreurs avec grâce : Les problèmes de réseau, les timeouts et les changements de sélecteurs se produisent
  4. Faites tourner les agents utilisateurs : Évitez la détection en variant les empreintes numériques des navigateurs
  5. Respectez le robots.txt : Vérifiez et suivez les politiques de scraping des sites web
  6. Utilisez l’isolement de contexte : Créez des contextes de navigateur séparés pour le scraping parallèle

Lors de la conversion du contenu scrapé en format markdown, envisagez d’utiliser des outils de conversion basés sur LLM ou des bibliothèques Python spécialisées pour la conversion HTML vers Markdown pour un résultat plus propre.

Pour les tests

  1. Utilisez les attributs data-testid : Plus stables que les classes CSS qui changent fréquemment
  2. Évitez les attentes dures : Utilisez les mécanismes d’attente intégrés de Playwright au lieu de sleep()
  3. Gardez les tests indépendants : Chaque test doit pouvoir s’exécuter en isolation
  4. Utilisez les fixtures : Partagez le code de configuration entre les tests de manière efficace
  5. Exécutez les tests en parallèle : Profitez des threads de travail de Playwright pour la vitesse
  6. Enregistrez les traces en cas d’échec : Activez l’enregistrement des traces pour un débogage plus facile

Optimisation des performances

# Désactiver les ressources inutiles
def fast_scraping():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        context = browser.new_context()
        page = context.new_page()

        # Bloquer les images et les feuilles de style pour accélérer le 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()

Comparaison de Playwright avec les alternatives

Playwright vs Selenium

Avantages de Playwright :

  • Attente automatique intégrée élimine les tests fragiles
  • Exécution plus rapide grâce à une architecture moderne
  • Meilleure interception et simulation du réseau
  • Outils de débogage supérieurs (Visionneuse de traces)
  • API plus simple avec moins de code boilerplate
  • Plusieurs navigateurs avec une seule installation

Avantages de Selenium :

  • Écosystème plus mature avec une communauté étendue
  • Prise en charge de plus de langages de programmation
  • Compatibilité avec plus de navigateurs y compris les anciennes versions

Playwright vs Puppeteer

Avantages de Playwright :

  • Prise en charge multi-navigateurs réelle (Firefox, WebKit, Chromium)
  • Meilleure conception d’API basée sur les leçons de Puppeteer
  • Outils de débogage plus puissants
  • Soutien de Microsoft et développement actif

Avantages de Puppeteer :

  • Empreinte légèrement plus petite
  • Expertise du Chrome DevTools Protocol

Pour la plupart des nouveaux projets, Playwright est le choix recommandé grâce à son architecture moderne et son ensemble de fonctionnalités complet. Si vous travaillez avec Go au lieu de Python ou JavaScript et que vous avez besoin de capacités de scraping web, consultez notre guide sur les Alternatives à Beautiful Soup pour Go pour des outils de scraping comparables dans l’écosystème Go.

Cas d’utilisation courants

Extraction de données pour les applications IA/LLM

Playwright est excellent pour collecter des données d’entraînement ou créer des capacités de recherche web pour les modèles d’IA. Lors de la construction de serveurs MCP (Model Context Protocol), Playwright peut gérer la composante de scraping web tandis que les LLM traitent le contenu extrait.

Tests automatisés dans les CI/CD

Intégrez les tests Playwright dans votre pipeline d’intégration continue :

# .github/workflows/playwright.yml
name: Tests Playwright
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: Installer les dépendances
      run: npm ci
    - name: Installer les navigateurs Playwright
      run: npx playwright install --with-deps
    - name: Exécuter les tests Playwright
      run: npx playwright test
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: rapport-playwright
        path: playwright-report/
        retention-days: 30

Surveillance des sites web

Surveillez vos sites de production pour la disponibilité et la fonctionnalité :

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)

            # Vérifier les éléments critiques
            assert page.is_visible('.header')
            assert page.is_visible('#main-content')

            print("✓ Le site est en bon état")
        except Exception as e:
            print(f"✗ Problème de site détecté : {e}")
            # Envoyer une alerte
        finally:
            browser.close()

# Exécuter toutes les 5 minutes
schedule.every(5).minutes.do(monitor_website)

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

Dépannage des problèmes courants

Problèmes d’installation des navigateurs

Si les navigateurs échouent à se télécharger :

# Définir un emplacement de téléchargement personnalisé
PLAYWRIGHT_BROWSERS_PATH=/custom/path playwright install

# Effacer le cache et réinstaller
playwright uninstall
playwright install

Erreurs de timeout

Augmentez les timeouts pour les réseaux lents ou les pages complexes :

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

Sélecteur non trouvé

Utilisez l’Inspecteur Playwright pour identifier les sélecteurs corrects :

PWDEBUG=1 pytest test_file.py

Cela ouvre l’inspecteur où vous pouvez survoler les éléments pour voir leurs sélecteurs.

Conclusion

Playwright représente la pointe de la technologie d’automatisation des navigateurs, combinant des fonctionnalités puissantes avec une excellente expérience de développement. Que vous construisiez un pipeline de scraping web, que vous mettiez en œuvre une couverture de tests complète ou que vous créiez des flux de travail automatisés, Playwright fournit les outils et la fiabilité dont vous avez besoin.

Ses mécanismes d’attente automatique éliminent les tests instables, le support multi-navigateurs garantit que vos applications fonctionnent partout, et les outils de débogage puissants rendent le dépannage simple. À mesure que les applications web continuent de croître en complexité, l’architecture moderne de Playwright et son développement actif en font un excellent choix pour tous les besoins d’automatisation des navigateurs.

Pour les développeurs Python travaillant sur des pipelines de données ou des projets de scraping web, Playwright s’intègre parfaitement avec les gestionnaires de paquets modernes et fonctionne excellemment aux côtés de pandas, requests et d’autres outils de science des données. La capacité d’extraire des données structurées à partir de sites web modernes complexes en fait un outil inestimable pour les applications d’IA, les projets de recherche et l’intelligence d’affaires. Lorsqu’il est combiné avec des outils de conversion HTML vers Markdown et un traitement de contenu approprié, Playwright devient une solution complète pour extraire, transformer et utiliser les données web à grande échelle.

Liens utiles

Autres références