Workflow n8n

Automatisation Google Sheets avec n8n : extraction de données web

Ce workflow n8n a pour objectif d'automatiser l'extraction de données depuis des URLs spécifiées dans Google Sheets, facilitant ainsi la collecte d'informations précieuses pour les entreprises. Dans un contexte où la rapidité et l'efficacité sont essentielles, ce processus permet aux équipes de gagner un temps considérable en évitant les tâches manuelles répétitives. Les cas d'usage incluent la veille concurrentielle, l'analyse de marché, ou encore la collecte de données pour des rapports d'activité. Étape 1 : le workflow commence par un déclencheur manuel, permettant à l'utilisateur de lancer le processus à tout moment. Étape 2 : il récupère les URLs à scraper depuis une feuille Google Sheets. Étape 3 : chaque URL est ensuite traitée par le nœud 'scrap url', qui effectue une requête HTTP pour obtenir le contenu de la page. Étape 4 : le contenu brut est nettoyé grâce au nœud 'clean html', préparant ainsi les données pour l'analyse. Étape 5 : les données extraites sont ensuite analysées par le modèle OpenRouter Chat, permettant une interprétation avancée. Enfin, les résultats sont ajoutés dans Google Sheets pour un suivi facile. En intégrant ce workflow, les entreprises peuvent réduire les erreurs humaines, améliorer la précision des données collectées et optimiser leur processus décisionnel. Tags clés : Google Sheets, automatisation, extraction de données.

Catégorie: Manual · Tags: Google Sheets, automatisation, extraction de données, n8n, web scraping0

Vue d'ensemble du workflow n8n

Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.

Détail des nœuds du workflow n8n

  • OpenRouter Chat Model

    Ce noeud utilise le modèle de chat OpenRouter pour générer des réponses basées sur les entrées fournies.

  • Structured Output Parser

    Ce noeud analyse et structure les données de sortie selon un schéma défini.

  • scrap url

    Ce noeud effectue une requête HTTP pour récupérer le contenu d'une URL spécifiée.

  • Sticky Note1

    Ce noeud crée une note autocollante avec le contenu fourni.

  • When clicking ‘Test workflow’

    Ce noeud déclenche manuellement l'exécution du workflow lorsque l'utilisateur clique sur 'Test workflow'.

  • url

    Ce noeud divise les éléments en plusieurs lots selon les options spécifiées.

  • get urls to scrape

    Ce noeud récupère des URL à partir d'une feuille Google Sheets selon les paramètres fournis.

  • clean html

    Ce noeud exécute un code JavaScript pour nettoyer le contenu HTML.

  • extract data

    Ce noeud extrait des données en utilisant un modèle de langage basé sur les messages et le texte fournis.

  • add results

    Ce noeud ajoute des résultats à une feuille Google Sheets selon les colonnes et options spécifiées.

  • Split items

    Ce noeud sépare les éléments en fonction d'un champ spécifique et des options fournies.

Inscris-toi pour voir l'intégralité du workflow

Inscription gratuite

S'inscrire gratuitementBesoin d'aide ?
{
  "meta": {
    "instanceId": "4a11afdb3c52fd098e3eae9fad4b39fdf1bbcde142f596adda46c795e366b326"
  },
  "nodes": [
    {
      "id": "f1b36f4b-6558-4e83-a999-e6f2d24e196c",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        620,
        240
      ],
      "parameters": {
        "model": "openai/gpt-4.1",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "89ca0a07-286f-4e68-9e85-0327a4859cc0",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        900,
        240
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"array\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"name\": { \"type\": \"string\" },\n      \"description\": { \"type\": \"string\" },\n      \"rating\": { \"type\": \"number\" },\n      \"reviews\": { \"type\": \"integer\" },\n      \"price\": { \"type\": \"string\" }\n    },\n    \"required\": [\"name\", \"description\", \"rating\", \"reviews\", \"price\"]\n  }\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "e4800c1d-c0d8-4093-81ec-fc19ad0034cd",
      "name": "scrap url",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        240,
        60
      ],
      "parameters": {
        "url": "https://api.brightdata.com/request",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "zone",
              "value": "web_unlocker1"
            },
            {
              "name": "url",
              "value": "={{ $json.url }}"
            },
            {
              "name": "format",
              "value": "raw"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "{{BRIGHTDATA_TOKEN}}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "1a1f768f-615d-4035-81b0-63b860f8e6ac",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -140
      ],
      "parameters": {
        "content": "## Web Scraper API\n\n[Inscription - Free Trial](https://get.brightdata.com/website-scraper)"
      },
      "typeVersion": 1
    },
    {
      "id": "2f260d96-4fff-4a4f-af29-1e43f465d54c",
      "name": "When clicking ‘Test workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -440,
        200
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "4be9033f-0b9f-466d-916e-88fbb2a80417",
      "name": "url",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        20,
        200
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "21b6d21c-b977-4175-9068-e0e2e19fa472",
      "name": "get urls to scrape",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -200,
        200
      ],
      "parameters": {
        "options": {},
        "sheetName": "{{TRACK_SHEET_GID}}",
        "documentId": "{{WEB_SHEET_ID}}"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "KsXWRZTrfCUFrrHD",
          "name": "Google Sheets"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "25ef76ec-cf0d-422e-b060-68c49192a008",
      "name": "clean html",
      "type": "n8n-nodes-base.code",
      "position": [
        460,
        60
      ],
      "parameters": {
        "jsCode": "// CleanHtmlFunction.js\n// Purpose: n8n Function node to clean HTML: remove doctype, scripts, styles, head, comments, classes, extra blank lines, and non-whitelisted tags\n\nreturn items.map(item => {\n  const rawHtml = item.json.data;\n\n  // 1) remove doctype, scripts, styles, comments and head section, and strip class attributes\n  let cleaned = rawHtml\n    .replace(/<!doctype html>/gi, '')\n    .replace(/<script[\\s\\S]*?<\\/script>/gi, '')\n    .replace(/<style[\\s\\S]*?<\\/style>/gi, '')\n    .replace(/<!--[\\s\\S]*?-->/g, '')\n    .replace(/<head[\\s\\S]*?<\\/head>/gi, '')\n    .replace(/\\sclass=\"[^\"]*\"/gi, '');\n\n  // 2) define whitelist of tags to keep\n  const allowedTags = [\n    'h1','h2','h3','h4','h5','h6',\n    'p','ul','ol','li',\n    'strong','em','a','blockquote',\n    'code','pre'\n  ];\n\n  // 3) strip out all tags not in the whitelist, reconstruct allowed tags cleanly\n  cleaned = cleaned.replace(\n    /<\\/?([a-z][a-z0-9]*)\\b[^>]*>/gi,\n    (match, tagName) => {\n      const name = tagName.toLowerCase();\n      if (allowedTags.includes(name)) {\n        return match.startsWith('</') ? `</${name}>` : `<${name}>`;\n      }\n      return '';\n    }\n  );\n\n  // 4) collapse multiple blank or whitespace-only lines into a single newline\n  cleaned = cleaned.replace(/(\\s*\\r?\\n\\s*){2,}/g, '\\n');\n\n  // 5) trim leading/trailing whitespace\n  cleaned = cleaned.trim();\n\n  return {\n    json: { cleanedHtml: cleaned }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "f72660d5-8427-4655-acbe-10365273c27b",
      "name": "extract data",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        680,
        60
      ],
      "parameters": {
        "text": "={{ $json.cleanedHtml }}",
        "messages": {
          "messageValues": [
            {
              "message": "=You are an expert in web page scraping. Provide a structured response in JSON format. Only the response, without commentary.\n\nExtract the product information for {{ $(‘url’).item.json.url.split(’/s?k=’)[1].split(’&’)[0] }} present on the page.\n\nname\ndescription\nrating\nreviews\nprice"
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.6
    },
    {
      "id": "8b4af1bb-d7f8-456e-b630-ecd9b6e4bcdc",
      "name": "add results",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1280,
        200
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $json.output.name }}",
            "price": "={{ $json.output.price }}",
            "rating": "={{ $json.output.rating }}",
            "reviews": "={{ $json.output.reviews }}",
            "description": "={{ $json.output.description }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string"
            },
            {
              "id": "description",
              "type": "string"
            },
            {
              "id": "rating",
              "type": "string"
            },
            {
              "id": "reviews",
              "type": "string"
            },
            {
              "id": "price",
              "type": "string"
            }
          ],
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": "{{RESULTS_SHEET_GID}}",
        "documentId": "{{WEB_SHEET_ID}}"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "KsXWRZTrfCUFrrHD",
          "name": "Google Sheets"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "7a5ba438-2ede-4d6c-b8fa-9a958ba1ef3e",
      "name": "Split items",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1060,
        60
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "output"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "url": {
      "main": [
        [],
        [
          {
            "node": "scrap url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "scrap url": {
      "main": [
        [
          {
            "node": "clean html",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "clean html": {
      "main": [
        [
          {
            "node": "extract data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split items": {
      "main": [
        [
          {
            "node": "add results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "add results": {
      "main": [
        [
          {
            "node": "url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "extract data": {
      "main": [
        [
          {
            "node": "Split items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get urls to scrape": {
      "main": [
        [
          {
            "node": "url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "extract data",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "extract data",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "get urls to scrape",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Pour qui est ce workflow ?

Ce workflow s'adresse principalement aux équipes marketing, aux analystes de données et aux responsables de la veille concurrentielle au sein des PME et grandes entreprises. Un niveau technique intermédiaire est recommandé pour une personnalisation efficace du flux.

Problème résolu

Ce workflow résout le problème de la collecte manuelle de données sur le web, qui peut être chronophage et sujette à des erreurs. En automatisant ce processus, les utilisateurs éliminent les frustrations liées à la recherche d'informations, réduisent les risques d'erreurs humaines et obtiennent des résultats fiables et exploitables rapidement. Cela permet également de libérer du temps pour se concentrer sur des tâches à plus forte valeur ajoutée.

Étapes du workflow

Étape 1 : le workflow est déclenché manuellement par l'utilisateur. Étape 2 : il récupère les URLs à scraper depuis Google Sheets. Étape 3 : chaque URL est traitée par le nœud 'scrap url' pour effectuer une requête HTTP. Étape 4 : le contenu brut est nettoyé via le nœud 'clean html'. Étape 5 : les données sont analysées par le modèle OpenRouter Chat. Étape 6 : les résultats sont ajoutés dans Google Sheets pour un suivi et une exploitation ultérieurs.

Guide de personnalisation du workflow n8n

Pour personnaliser ce workflow, commencez par modifier le nœud 'get urls to scrape' en spécifiant le nom de votre feuille Google Sheets et l'ID du document. Vous pouvez également ajuster le nœud 'scrap url' pour changer l'URL cible ou les paramètres de la requête HTTP. Si nécessaire, adaptez le code dans le nœud 'clean html' pour mieux traiter le contenu selon vos besoins. Enfin, assurez-vous que le nœud 'add results' est configuré pour écrire dans la bonne feuille et les bonnes colonnes de votre Google Sheets.