Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 60

Implémentation des Modules de Collecte et Transformation de Données

Recommended resources

Bonjour !

Dans la leçon précédente, vous avez joué le rôle d'architecte de solutions en concevant et en documentant le système de veille concurrentielle qui constitue notre projet final. Vous avez décomposé le problème, défini les workflows et anticipé les exigences de production. Ce plan solide est notre feuille de route pour la phase d'implémentation.

Nous passons maintenant à la deuxième partie du projet. Conformément à l'objectif d'apprentissage, vous allez implémenter les modules de collecte de données et de transformation (scraping, API, IA). Aujourd'hui, nous allons transformer votre architecture en un workflow n8n fonctionnel, en nous concentrant sur le cœur du traitement de la donnée.

1. La Collecte de Données : Stratégie de Scraping Robuste

Le cahier des charges exige de scraper quotidiennement une page de "nouveautés" d'un site e-commerce. Comme nous l'avons vu dans le module 8, un scraping direct avec le nœud HTTP Request peut être fragile face aux protections anti-bots, au contenu dynamique (JavaScript) et aux changements de structure du site.

Pour un système de production, une approche plus fiable consiste à déléguer le scraping à un service spécialisé. Ces plateformes, comme Apify ou Bright Data, sont conçues pour gérer ces complexités.

La vidéo suivante est un excellent guide qui montre comment orchestrer un service de scraping (Apify) depuis n8n, y intégrer de l'IA, et structurer la sortie.

Scraper N’IMPORTE QUEL SITE avec N8N & Apify (Guide Ultime 2025)

Regardez cette vidéo de Meydeey, "Scraper N’IMPORTE QUEL SITE avec N8N & Apify", pour comprendre la logique globale. Elle illustre parfaitement l'orchestration d'un scraper externe et l'enchaînement avec un traitement IA, ce qui correspond exactement à notre projet.

Concentrez-vous sur ces deux parties clés : Configuration d'Apify (04:10 - 10:08) : Observez comment l'acteur "Website Content Crawler" est configuré. Dans notre cas, nous utiliserions plutôt un acteur comme "Web Scraper" qui permet d'extraire des données structurées (prix, nom, etc.) via des sélecteurs CSS, mais le principe de configuration et de test manuel reste le même. Intégration n8n (10:08 - 15:30) : C'est la partie la plus importante. Portez attention à la manière dont le nœud HTTP Request est utilisé pour lancer l'acteur Apify. Notez la configuration de l'authentification (clé API) et la construction du corps de la requête (body) en JSON pour passer des paramètres dynamiques comme l'URL à scraper.

Mise en Pratique : Simulation de l'Étape de Collecte

Configurer un scraper Apify complet pour un site fictif sort du cadre de cette leçon. Pour nous concentrer sur la logique n8n, nous allons simuler la sortie du scraper.

Créez un nouveau workflow, nommez-le [Projet Final] - Collecte et Transformation Produits, et suivez ces étapes :

  1. Déclencheur Manuel : Ajoutez un nœud Start.

  2. Simulation du Scraper : Ajoutez un nœud Code. Ce nœud jouera le rôle de notre scraper Apify en fournissant des données de test. Copiez-y le code JavaScript suivant :

    // Ce nœud simule la sortie d'un scraper Apify ou Bright Data.
    // Il retourne une liste de produits avec leurs informations de base.
    return [
      {
        json: {
          name: "T-shirt en Coton Bio",
          priceUSD": 29.99,
          productURL: "https://example-competitor.com/product/t-shirt-bio",
          imageURL: "https://example-competitor.com/images/tshirt.jpg"
        }
      },
      {
        json: {
          name: "Jean Slim-Fit Recyclé",
          priceUSD": 89.50,
          productURL: "https://example-competitor.com/product/jean-slim",
          imageURL: "https://example-competitor.com/images/jean.jpg"
        }
      },
      {
        json: {
          name: "Baskets Véganes Blanches",
          priceUSD": 119.00,
          productURL: "https://example-competitor.com/product/baskets-vegan",
          imageURL: "https://example-competitor.com/images/baskets.jpg"
        }
      }
    ];
    

Exécutez ce nœud. Vous devriez voir en sortie une liste de 3 items, chacun contenant un objet JSON avec les détails d'un produit. C'est notre point de départ pour la transformation.


2. Implémentation de la Transformation et de l'Enrichissement

Maintenant que nous avons nos données brutes, nous allons les enrichir en suivant le cahier des charges. n8n traite les items un par un, ce qui est parfait pour appliquer notre logique à chaque produit.

n8n Workflow for Web Data Extraction, AI Processing, and Google Sheet Update
Ce schéma illustre un flux similaire à celui que nous allons construire : récupération de données, traitement en série (requête, nettoyage, IA), et mise à jour d'une destination finale.

A. Conversion de Devise (Appel API)

Pour chaque produit, nous devons convertir le prix de USD en EUR.

  1. Ajouter un nœud HTTP Request :

    • URL : https://api.frankfurter.app/latest?from=USD&to=EUR
    • Method : GET
    • Send/Accept : Laissez JSON.
    • Renommez ce nœud en API: Get EUR Rate.
  2. Exécuter et inspecter : Exécutez le workflow. Le nœud API: Get EUR Rate devrait retourner un objet JSON avec le taux de change actuel dans rates.EUR.

  3. Ajouter un nœud Set : Placez-le après le nœud HTTP Request.

    • Renommez-le SET: Add priceEUR.
    • Activez l'option Keep Only Set.
    • Créez une nouvelle valeur :
      • Name : priceEUR
      • Value : Cliquez sur l'icône </> pour ouvrir l'éditeur d'expressions. Nous allons multiplier le prix en USD par le taux de change récupéré.
        • Récupérez le prix de l'item en cours : {{ $json.priceUSD }}.
        • Récupérez le taux de change du nœud précédent : {{ $('API: Get EUR Rate').json.rates.EUR }}.
        • L'expression complète est : {{ $json.priceUSD * $('API: Get EUR Rate').json.rates.EUR }}.
    • Pour garder les données d'origine, vous devez les recréer dans le nœud Set. Ajoutez les valeurs suivantes :
      • name: {{ $json.name }}
      • priceUSD: {{ $json.priceUSD }}
      • productURL: {{ $json.productURL }}
      • imageURL: {{ $json.imageURL }}

Exécutez à nouveau. La sortie du nœud Set doit maintenant contenir un champ priceEUR pour chaque produit.

Note : Pour plus de propreté, vous pourriez utiliser un nœud Edit Fields qui permet d'ajouter/modifier des champs sans avoir à redéfinir tous les autres.

B. Génération de Description (Traitement IA)

L'étape suivante consiste à générer une description marketing pour chaque produit à l'aide d'un LLM.

  1. Ajouter un nœud OpenAI (ou le nœud de votre fournisseur LLM préféré) :

    • Authentication : Connectez vos credentials. Vous devrez obtenir une clé API depuis la plateforme OpenAI.
    • Resource : Chat
    • Operation : Send Message
    • Model : Choisissez un modèle (ex: gpt-4o-mini ou gpt-3.5-turbo pour un bon compromis coût/performance).
    • Message Content : C'est ici que vous formulez votre prompt. Utilisez une expression pour le rendre dynamique :
      Tu es un expert en marketing e-commerce. Rédige une description percutante et concise (2-3 phrases) pour le produit suivant : "{{ $json.name }}". Mets en avant un bénéfice client clair. Le ton doit être professionnel mais engageant.
      
    • Renommez le nœud IA: Generate Description.
  2. Ajouter un autre nœud Set :

    • Renommez-le SET: Add AI Description.
    • Comme précédemment, activez Keep Only Set et recréez tous les champs existants (name, priceUSD, priceEUR, etc.) en récupérant leurs valeurs depuis le nœud SET: Add priceEUR.
    • Ajoutez la nouvelle valeur :
      • Name : description
      • Value : L'expression pour récupérer la réponse de l'IA est {{ $('IA: Generate Description').json.choices[0].message.content }}.

3. Assemblage Final et Validation

À ce stade, votre workflow devrait ressembler à ceci :
Start -> Code (Simulate Scraper) -> API: Get EUR Rate -> SET: Add priceEUR -> IA: Generate Description -> SET: Add AI Description.

Exécutez le workflow complet. Cliquez sur la sortie du dernier nœud (SET: Add AI Description). Vous devriez voir une liste de 3 items. Inspectez chaque item : il doit maintenant contenir l'ensemble des informations requises par le cahier des charges pour l'étape de stockage : name, priceUSD, priceEUR, productURL, imageURL, et description.

Félicitations, vous avez construit le moteur de traitement de données de votre projet !

Pour vous permettre de vérifier votre travail, voici le code JSON complet du workflow que nous venons de construire. Vous pouvez le copier et l'importer dans n8n (Ctrl/Cmd + I) pour le comparer au vôtre.

{
  "name": "[Projet Final] - Collecte et Transformation Produits",
  "nodes": [
    {
      "parameters": {},
      "id": "595f9c5d-3571-464a-a719-21a113ac474f",
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        480,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Ce nœud simule la sortie d'un scraper Apify ou Bright Data.\n// Il retourne une liste de produits avec leurs informations de base.\nreturn [\n  {\n    json: {\n      name: \"T-shirt en Coton Bio\",\n      \"priceUSD\": 29.99,\n      productURL: \"https://example-competitor.com/product/t-shirt-bio\",\n      imageURL: \"https://example-competitor.com/images/tshirt.jpg\"\n    }\n  },\n  {\n    json: {\n      name: \"Jean Slim-Fit Recyclé\",\n      \"priceUSD\": 89.50,\n      productURL: \"https://example-competitor.com/product/jean-slim\",\n      imageURL: \"https://example-competitor.com/images/jean.jpg\"\n    }\n  },\n  {\n    json: {\n      name: \"Baskets Véganes Blanches\",\n      \"priceUSD\": 119.00,\n      productURL: \"https://example-competitor.com/product/baskets-vegan\",\n      imageURL: \"https://example-competitor.com/images/baskets.jpg\"\n    }\n  }\n];"
      },
      "id": "b9685a73-61a7-4b72-a1f9-9060b9409893",
      "name": "Simulate Scraper",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        700,
        300
      ]
    },
    {
      "parameters": {
        "url": "https://api.frankfurter.app/latest?from=USD&to=EUR",
        "options": {}
      },
      "id": "31b09b53-43f9-4623-a261-7589ed9910d5",
      "name": "API: Get EUR Rate",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        920,
        300
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "name",
              "value": "={{ $json.name }}"
            },
            {
              "name": "productURL",
              "value": "={{ $json.productURL }}"
            },
            {
              "name": "imageURL",
              "value": "={{ $json.imageURL }}"
            }
          ],
          "number": [
            {
              "name": "priceUSD",
              "value": "={{ $json.priceUSD }}"
            },
            {
              "name": "priceEUR",
              "value": "={{ $json.priceUSD * $('API: Get EUR Rate').json.rates.EUR }}"
            }
          ]
        },
        "options": {}
      },
      "id": "c0e64391-4d43-4e42-998f-4abf472251f2",
      "name": "SET: Add priceEUR",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2.1,
      "position": [
        1140,
        300
      ]
    },
    {
      "parameters": {
        "model": "gpt-4o-mini",
        "message": "={{ `Tu es un expert en marketing e-commerce. Rédige une description percutante et concise (2-3 phrases) pour le produit suivant : \"${$json.name}\". Mets en avant un bénéfice client clair. Le ton doit être professionnel mais engageant.` }}",
        "options": {}
      },
      "id": "67026771-ef62-4467-b508-ba9013c72709",
      "name": "IA: Generate Description",
      "type": "n8n-nodes-base.openAiChat",
      "typeVersion": 2,
      "position": [
        1360,
        300
      ],
      "credentials": {
        "openAiApi": {
          "id": "YOUR_CREDENTIAL_ID",
          "name": "OpenAI account"
        }
      }
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "name",
              "value": "={{ $('SET: Add priceEUR').json.name }}"
            },
            {
              "name": "productURL",
              "value": "={{ $('SET: Add priceEUR').json.productURL }}"
            },
            {
              "name": "imageURL",
              "value": "={{ $('SET: Add priceEUR').json.imageURL }}"
            },
            {
              "name": "description",
              "value": "={{ $('IA: Generate Description').json.choices[0].message.content }}"
            }
          ],
          "number": [
            {
              "name": "priceUSD",
              "value": "={{ $('SET: Add priceEUR').json.priceUSD }}"
            },
            {
              "name": "priceEUR",
              "value": "={{ $('SET: Add priceEUR').json.priceEUR }}"
            }
          ]
        },
        "options": {}
      },
      "id": "37f40775-555e-4172-acbf-031024bd3f4f",
      "name": "SET: Add AI Description",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2.1,
      "position": [
        1580,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Simulate Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simulate Scraper": {
      "main": [
        [
          {
            "node": "API: Get EUR Rate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "API: Get EUR Rate": {
      "main": [
        [
          {
            "node": "SET: Add priceEUR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SET: Add priceEUR": {
      "main": [
        [
          {
            "node": "IA: Generate Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IA: Generate Description": {
      "main": [
        [
          {
            "node": "SET: Add AI Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Conclusion

Points clés à retenir :

  • Orchestration de Services Externes : Vous avez implémenté une architecture robuste en simulant un appel à un service de scraping externe, puis en appelant réellement une API de conversion et un service d'IA.
  • Traitement de Données en Série : Vous avez construit un pipeline qui enrichit progressivement les données, chaque nœud ajoutant de la valeur à l'item traité.
  • Expressions Dynamiques : Vous avez utilisé des expressions n8n pour passer des données entre les nœuds, rendant votre workflow flexible et puissant.

Aperçu de la prochaine leçon :
Le cœur de notre système est maintenant fonctionnel. Dans la dernière partie de notre projet, nous finaliserons le système de bout en bout. Nous prendrons la sortie de ce workflow pour implémenter le stockage en base de données, la notification sur Slack, et le système de gestion d'erreurs, transformant ainsi notre prototype en une solution d'automatisation complète et prête pour la production.