使用Claude AI和竞品分析的SEO内容生成器
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 36 个节点。主要使用 If, Code, Filter, HttpRequest, GoogleSheets 等节点。 使用Claude AI和Apify竞品分析生成SEO内容
前置要求
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
- •Anthropic API Key
使用的节点 (36)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "393ca9e36a1f81b0f643c72792946a5fe5e49eb4864181ba4032e5a408278263"
},
"nodes": [
{
"id": "2563146e-dbdb-498a-b213-8beb82534f50",
"name": "过滤器1",
"type": "n8n-nodes-base.filter",
"position": [
272,
544
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d0a801f4-942f-4f2b-b71f-f31f23066f28",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json['Keyword'] }}",
"rightValue": ""
},
{
"id": "6e0d041d-30cd-413d-913d-3c1775840277",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json['<h1>'] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "44cb6085-acf9-4645-a78e-849f3d6e8fe3",
"name": "条件判断1",
"type": "n8n-nodes-base.if",
"position": [
464,
544
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b5344169-b18b-482d-9d03-b02c170668b9",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json['Keyword'] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1e886a0f-1e95-4285-a63a-751206f23b12",
"name": "Anthropic 聊天模型2",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
2448,
736
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-20250514",
"cachedResultName": "Claude Sonnet 4"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"id": "WXQf5QsxCs3AyxlW",
"name": "Anthropic account"
}
},
"typeVersion": 1.3
},
{
"id": "06872cb6-5c22-4864-aff4-6e1c605ae0f4",
"name": "结构化输出解析器",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2944,
736
],
"parameters": {
"jsonSchemaExample": "{\n\t\"meta_title\": \"Courtage Assurance : Services & Avantages d'un Courtier en 2023\",\n\t\"meta_description\": \"Découvrez comment optimiser votre compte de libre passage avec Revolution. Conseils d'experts pour maximiser votre capital retraite et faire les meilleurs choix. Consultez-nous !\",\n \"h1\": \"Compte de libre passage : Guide complet pour gérer votre 2e pilier\"\n}"
},
"typeVersion": 1.2
},
{
"id": "0c1e0c3c-d015-4689-97ef-76319f453b96",
"name": "Anthropic 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
3312,
736
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-20250514",
"cachedResultName": "Claude Sonnet 4"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"id": "WXQf5QsxCs3AyxlW",
"name": "Anthropic account"
}
},
"typeVersion": 1.3
},
{
"id": "e1c3a867-eee8-48b4-8d30-df7c0cee24c2",
"name": "标题 1",
"type": "n8n-nodes-base.code",
"position": [
1888,
32
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "e155b00c-2cea-4d8d-a80b-6a0b5089b235",
"name": "标题 2",
"type": "n8n-nodes-base.code",
"position": [
1888,
256
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "2e536985-af39-48cd-83d4-a3513899f4f0",
"name": "标题 3",
"type": "n8n-nodes-base.code",
"position": [
1888,
480
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "8acc9d62-9d55-445e-a858-c733d6e6b68c",
"name": "标题 4",
"type": "n8n-nodes-base.code",
"position": [
1888,
688
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "659ebdb8-e76d-494c-96de-b257d9888461",
"name": "标题 5",
"type": "n8n-nodes-base.code",
"position": [
1888,
880
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "74000c37-8dd3-47e7-bb55-3cd7532c1274",
"name": "代码",
"type": "n8n-nodes-base.code",
"position": [
4016,
528
],
"parameters": {
"jsCode": "// Code avec conservation de toutes les colonnes existantes\nconst items = [];\n\n// Récupérer les données de vos différents nodes\nconst loopItem = $('Loop Over Items').item.json;\nconst metaTagsOutput = $('Meta tag + h1').item.json.output;\nconst briefOutput = $json.output;\n\n// Créer l'objet avec toutes les colonnes et le mapping des nouvelles valeurs\nconst transformedItem = {\n // Copier toutes les propriétés existantes\n ...loopItem,\n \n // Écraser/ajouter les nouvelles valeurs\n '<title>': metaTagsOutput.meta_title,\n '<meta-desc>': metaTagsOutput.meta_description,\n '<h1>': metaTagsOutput.h1,\n 'brief': briefOutput\n};\n\n// Retourner l'item transformé\nitems.push(transformedItem);\n\nreturn items;"
},
"typeVersion": 2
},
{
"id": "d90859a4-bf2b-48b4-9180-ee001cb7bf58",
"name": "Apify",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
544
],
"parameters": {
"url": "https://api.apify.com/v2/acts/nFJndFXA5zjCTuudP/run-sync-get-dataset-items",
"method": "POST",
"options": {
"timeout": 300000,
"response": {
"response": {
"responseFormat": "json"
}
}
},
"jsonBody": "={\n \"countryCode\": \"fr\",\n \"forceExactMatch\": false,\n \"includeIcons\": false,\n \"includeUnfilteredResults\": false,\n \"languageCode\": \"fr\",\n \"maxPagesPerQuery\": 1,\n \"mobileResults\": false,\n \"queries\": \"{{ $json['Keyword'] }}\",\n \"resultsPerPage\": 10,\n \"saveHtml\": false,\n \"saveHtmlToKeyValueStore\": false\n}",
"sendBody": true,
"sendQuery": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "timeout",
"value": "240"
},
{
"name": "memory",
"value": "512"
},
{
"name": "maxItems",
"value": "10"
},
{
"name": "format",
"value": "json"
},
{
"name": "maxTotalChargeUsd",
"value": "0.50"
}
]
},
"nodeCredentialType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "jAy18eDHHP2ZoGrH",
"name": "Apify"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "cf903821-ca3a-44f8-924c-9d2d280bb2f3",
"name": "在工作表中更新行",
"type": "n8n-nodes-base.googleSheets",
"position": [
4368,
528
],
"parameters": {
"columns": {
"value": {},
"schema": [
{
"id": "Niv 0",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 0",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Niv 1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Niv 2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Niv 3",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "mots clés",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "mots clés",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "vol",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "vol",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "KD%",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "KD%",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type de page",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Type de page",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "URL",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "<title>",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "<title>",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "<meta-desc>",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "<meta-desc>",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "<h1>",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "<h1>",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "brief",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "brief",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "mots clés secondaires",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "mots clés secondaires",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "intentions de recherche",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "intentions de recherche",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "nombre de mots",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "nombre de mots",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Premiere version",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Premiere version",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Thot",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Thot",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "col_11",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "col_11",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "col_13",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "col_13",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "col_15",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "col_15",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [
"mots clés"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "FR"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "wBRLUCktxqXE6DVJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "cb78803f-39aa-4634-a551-bece02c2a548",
"name": "抓取 1",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
1616,
32
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[0].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "b0ec431f-99c9-452c-866f-b5bf167b69a1",
"name": "抓取 2",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
1616,
256
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[1].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "a7e82453-e1f5-4010-8f30-7cf09146165f",
"name": "抓取 5",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
1616,
880
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[4].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "78a4da3e-6249-4462-8a12-bba576445077",
"name": "抓取 4",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
1616,
688
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[3].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "40b057e3-87a1-4bf8-ae6e-a9815efaa7ff",
"name": "抓取 3",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
1616,
480
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[2].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "aed07f3a-0ba8-4c92-a850-0c0220b88d7c",
"name": "客户信息",
"type": "n8n-nodes-base.googleSheets",
"position": [
-176,
544
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Client information"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "wBRLUCktxqXE6DVJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "f4904275-5cb3-4beb-9450-90fe2531ec63",
"name": "SEO 信息",
"type": "n8n-nodes-base.googleSheets",
"position": [
48,
544
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "SEO"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "wBRLUCktxqXE6DVJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "89682183-704d-4c21-9a32-baa0a2563cb6",
"name": "当收到聊天消息时",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-448,
544
],
"webhookId": "88a8efaa-7712-49bd-ba94-4bb130719dbe",
"parameters": {
"mode": "webhook",
"public": true,
"options": {
"responseMode": "responseNode"
}
},
"typeVersion": 1.1
},
{
"id": "3b94e750-0ad8-433d-aa83-86bc70479bea",
"name": "遍历项目",
"type": "n8n-nodes-base.splitInBatches",
"position": [
704,
528
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "a61be69b-6a4a-42f2-9955-e76b9b65d2ba",
"name": "Meta 标签 + H1",
"type": "@n8n/n8n-nodes-langchain.agent",
"maxTries": 5,
"position": [
2576,
528
],
"parameters": {
"text": "=[Main keyword]: {{ $('Loop Over Items').item.json['Keyword'] }}\n\n[Page]: {{ $('SEO information').item.json.Page }}\n\n[Site]: {{ $('Client Information').item.json['Client name'] }} ({{ $('Client Information').item.json['Client information'] }})\n\n[Description]:{{ $('Loop Over Items').item.json.Description }}\n\n[Competitor info]:\n\nCompetitor 1:\n{{ $('Apify').item?.json?.organicResults?.[0]?.url || '' }}\n\nMeta title: {{ $('Apify').item?.json?.organicResults?.[0]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[0]?.description || '' }}\n{{ $('Titre 1').item.json.h1 }}\n\nCompetitor 2:\n{{ $('Apify').item?.json?.organicResults?.[1]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[1]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[1]?.description || '' }}\n{{ $('Titre 2').item.json.h1 }}\n\nCompetitor 3:\n{{ $('Apify').item?.json?.organicResults?.[2]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[2]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[2]?.description || '' }}\n{{ $('Titre 3').item.json.h1 }}\n\nCompetitor 4:\n{{ $('Apify').item?.json?.organicResults?.[3]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[3]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[3]?.description || '' }}\n{{ $('Titre 4').item.json.h1 }}\n\nCompetitor 5:\n{{ $('Apify').item?.json?.organicResults?.[4]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[4]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[4]?.description || '' }}\n{{ $('Titre 5').item.json.h1 }}\n\n[Client name]: {{ $('Client Information').item.json['Client name'] }}",
"options": {
"systemMessage": "# Rules\n\nAs an SEO expert, I need you to analyze the [Main keyword] for the page [Page], for the site [Site]. You also have a short description [Description] of what the page is about. You must also analyze the competitor info [Competitor info] (url, meta title, meta description, h1)\n\n# Deliverables\n\nto provide the following elements:\n\nMETA TITLE (65 characters maximum):\nCreate a catchy and optimized meta title that includes the main keyword at the beginning of the title if possible, while remaining natural and click-inducing. The format should be in sentence case. Expected structure for the title: Main keyword, cta (do not include the [Client name] in the title)\n\nMETA DESCRIPTION (165 characters maximum):\nWrite a persuasive meta description that clearly summarizes the page's added value, includes the main keyword and features an effective call-to-action.\n\nH1 (70 characters maximum):\nPropose an impactful H1 that integrates the main keyword while being attractive to the user. The format should be in sentence case.\n\nDo not write an introduction or conclusion to your response."
},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 1.9,
"waitBetweenTries": 5000
},
{
"id": "72cff01f-82e0-4021-9f6b-b3b373b93a59",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-496,
448
],
"parameters": {
"color": 2,
"width": 1360,
"height": 256,
"content": "# 阶段 1:数据输入与配置"
},
"typeVersion": 1
},
{
"id": "6c894ea3-f23e-422b-9050-5c22827a0aba",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
-32
],
"parameters": {
"color": 3,
"width": 1248,
"height": 1072,
"content": "# 阶段 2:竞争对手研究与分析"
},
"typeVersion": 1
},
{
"id": "114d2259-481b-4173-9346-f1d51958a541",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2400,
448
],
"parameters": {
"color": 5,
"width": 656,
"height": 560,
"content": "# 阶段 3:Meta 标签和 H1 生成"
},
"typeVersion": 1
},
{
"id": "b2a2e14f-5fa2-4334-a03d-6ef0cc761461",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
3968,
448
],
"parameters": {
"color": 7,
"width": 560,
"height": 256,
"content": "# 阶段 5:数据集成与表格更新"
},
"typeVersion": 1
},
{
"id": "d8821a1e-3295-457f-8d60-53df802859f2",
"name": "便利贴5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1152,
224
],
"parameters": {
"color": 4,
"width": 544,
"height": 944,
"content": "# 阶段 0:设置与配置"
},
"typeVersion": 1
},
{
"id": "c9d8682d-ad2b-4ba0-9b80-62cda1c98962",
"name": "便签 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-496,
752
],
"parameters": {
"color": 2,
"width": 1360,
"height": 464,
"content": "### 您需要做的:"
},
"typeVersion": 1
},
{
"id": "60d1d1e6-1e99-48fc-98f7-77c0731f54be",
"name": "便签 7",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
1088
],
"parameters": {
"color": 3,
"width": 1248,
"height": 368,
"content": "### 系统会做的:"
},
"typeVersion": 1
},
{
"id": "34828cbe-a9d1-4a81-81e6-b9e2024475e3",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2400,
1056
],
"parameters": {
"color": 5,
"width": 656,
"height": 384,
"content": "### 系统会做的:"
},
"typeVersion": 1
},
{
"id": "bf5d8681-ddd6-4bc6-ae9e-46637a155811",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
3200,
448
],
"parameters": {
"color": 6,
"width": 656,
"height": 560,
"content": "# 阶段 4:内容简报创建"
},
"typeVersion": 1
},
{
"id": "a797dbaa-905a-413d-83bc-3011e4202906",
"name": "内容简报",
"type": "@n8n/n8n-nodes-langchain.agent",
"maxTries": 5,
"position": [
3424,
528
],
"parameters": {
"text": "=[Site]: {{ $('Client Information').item.json['Client name'] }}({{ $('Client Information').item.json['Client information'] }})\n[Main keyword]: {{ $('Loop Over Items').item.json.Keyword }}\n[h1]: {{ $('Meta tag + h1').item.json.output.h1 }}\n[Description]: {{ $('Loop Over Items').item.json.Description }}\n[Awareness]: {{ $('Loop Over Items').item.json['Awareness level'] }}\n[Competitor info]:\nCompetitor 1:\n{{ $('Apify').item.json.organicResults[0].url }}\n{{ $('Titre 1').item.json.h1 }}\n{{ $('Titre 1').item.json.h2 }}\n{{ $('Titre 1').item.json.h3 }}\n{{ $('Titre 1').item.json.h4 }}\n{{ $('Titre 1').item.json.h5 }}\n{{ $('Titre 1').item.json.h6 }}\nCompetitor 2:\n{{ $('Apify').item.json.organicResults[1].url }}\n{{ $('Titre 2').item.json.h1 }}\n{{ $('Titre 2').item.json.h2 }}\n{{ $('Titre 2').item.json.h3 }}\n{{ $('Titre 2').item.json.h4 }}\n{{ $('Titre 2').item.json.h5 }}\n{{ $('Titre 2').item.json.h6 }}\nCompetitor 3:\n{{ $('Apify').item.json.organicResults[2].url }}\n{{ $('Titre 3').item.json.h1 }}\n{{ $('Titre 3').item.json.h2 }}\n{{ $('Titre 3').item.json.h3 }}\n{{ $('Titre 3').item.json.h4 }}\n{{ $('Titre 3').item.json.h5 }}\n{{ $('Titre 3').item.json.h6 }}\nCompetitor 4:\n{{ $('Apify').item.json.organicResults[3].url }}\n{{ $('Titre 4').item.json.h1 }}\n{{ $('Titre 4').item.json.h2 }}\n{{ $('Titre 4').item.json.h3 }}\n{{ $('Titre 4').item.json.h4 }}\n{{ $('Titre 4').item.json.h5 }}\n{{ $('Titre 4').item.json.h6 }}\nCompetitor 5:\n{{ $('Apify').item.json.organicResults[4].url }}\n{{ $('Titre 5').item.json.h1 }}\n{{ $('Titre 5').item.json.h2 }}\n{{ $('Titre 5').item.json.h3 }}\n{{ $('Titre 5').item.json.h4 }}\n{{ $('Titre 5').item.json.h5 }}\n{{ $('Titre 5').item.json.h6 }}\n[Page type]: {{ $('Loop Over Items').item.json['Type de page'] ? $('Loop Over Items').item.json['Type de page'] : '' }}\n[Client name]: {{ $('Client Information').item.json['Client name'] }}",
"options": {
"systemMessage": "# Rules\n\nI want to create an SEO content brief for a web page for the site [Site]. The main keyword I'm targeting is [Main keyword] and the h1 is the following [h1]. Here's a short description of the page [Description] And here's the awareness level that corresponds to the page [Awareness] Here's additional information about competitors positioning on this keyword, use this as inspiration to respond to the request [Competitor info]\n\n# Deliverables\n\nCan you provide a complete content brief including:\n\nPage type: [Page type]\nDetailed analysis of the search intent behind the main keyword (informational, transactional, navigational as percentages for each intent)\nStrategy to highlight the company in this content based on the main keyword\nRich media suggestions to integrate (images, videos, infographics, tables, etc.)\nDetailed MECE (Mutually Exclusive, Collectively Exhaustive) page structure with:\n\nthe h1 [h1]\nIntroduction\nH2 sections with key points for each section\nH3 subsections if necessary\n\n\nRecommended level of detail for writing on a scale of 1 to 10\n\nPlease ensure that the proposed structure is coherent, exhaustive, without redundancies, and optimized for SEO while remaining relevant for users.\nDo not write an introduction or conclusion to your response."
},
"promptType": "define"
},
"retryOnFail": true,
"typeVersion": 1.9,
"waitBetweenTries": 5000
},
{
"id": "eab92685-858d-41ca-bee7-488ca35b84b5",
"name": "便签 9",
"type": "n8n-nodes-base.stickyNote",
"position": [
3200,
1056
],
"parameters": {
"color": 6,
"width": 656,
"height": 400,
"content": "### 系统会做的:"
},
"typeVersion": 1
},
{
"id": "22e206d0-4226-4c0d-abe0-a6bc8af1c1fc",
"name": "便签10",
"type": "n8n-nodes-base.stickyNote",
"position": [
3968,
752
],
"parameters": {
"color": 7,
"width": 560,
"height": 416,
"content": "### 系统会做的:"
},
"typeVersion": 1
},
{
"id": "4a6e883c-ada1-4a1c-a0c0-7c50772d2e45",
"name": "便签13",
"type": "n8n-nodes-base.stickyNote",
"position": [
-192,
-80
],
"parameters": {
"width": 816,
"height": 336,
"content": "## 需要更高级的自动化解决方案?联系我们获取定制企业工作流!"
},
"typeVersion": 1
}
],
"pinData": {
"When chat message received": [
{
"action": "sendMessage",
"chatInput": "t",
"sessionId": "bae7e54a70ab4df5a59a2f8841897496"
}
]
},
"connections": {
"If1": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Update row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Apify": {
"main": [
[
{
"node": "Scrape 1",
"type": "main",
"index": 0
}
]
]
},
"Filter1": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Titre 1": {
"main": [
[
{
"node": "Scrape 2",
"type": "main",
"index": 0
}
]
]
},
"Titre 2": {
"main": [
[
{
"node": "Scrape 3",
"type": "main",
"index": 0
}
]
]
},
"Titre 3": {
"main": [
[
{
"node": "Scrape 4",
"type": "main",
"index": 0
}
]
]
},
"Titre 4": {
"main": [
[
{
"node": "Scrape 5",
"type": "main",
"index": 0
}
]
]
},
"Titre 5": {
"main": [
[
{
"node": "Meta tag + h1",
"type": "main",
"index": 0
}
]
]
},
"Scrape 1": {
"main": [
[
{
"node": "Titre 1",
"type": "main",
"index": 0
}
]
]
},
"Scrape 2": {
"main": [
[
{
"node": "Titre 2",
"type": "main",
"index": 0
}
]
]
},
"Scrape 3": {
"main": [
[
{
"node": "Titre 3",
"type": "main",
"index": 0
}
]
]
},
"Scrape 4": {
"main": [
[
{
"node": "Titre 4",
"type": "main",
"index": 0
}
]
]
},
"Scrape 5": {
"main": [
[
{
"node": "Titre 5",
"type": "main",
"index": 0
}
]
]
},
"Content brief": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Meta tag + h1": {
"main": [
[
{
"node": "Content brief",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Apify",
"type": "main",
"index": 0
}
]
]
},
"SEO information": {
"main": [
[
{
"node": "Filter1",
"type": "main",
"index": 0
}
]
]
},
"Client Information": {
"main": [
[
{
"node": "SEO information",
"type": "main",
"index": 0
}
]
]
},
"Update row in sheet": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Chat Model": {
"ai_languageModel": [
[
{
"node": "Content brief",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Anthropic Chat Model2": {
"ai_languageModel": [
[
{
"node": "Meta tag + h1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser2": {
"ai_outputParser": [
[
{
"node": "Meta tag + h1",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Client Information",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用Claude AI、竞品分析和Supabase RAG的SEO内容生成器
使用Claude AI、竞品分析和Supabase RAG生成SEO内容
If
Code
Filter
+11
40 节点Growth AI
内容创作
从Google Sheets生成SEO锚文本
使用Claude 4 Sonnet从Google Sheets生成SEO锚文本
Code
Filter
Google Sheets
+5
19 节点Growth AI
内容创作
使用Claude AI从Google Sheets到WordPress生成无障碍替代文本
使用Claude AI从Google Sheets到WordPress生成无障碍替代文本
If
Code
Http Request
+5
10 节点Growth AI
内容创作
使用 BOAMP API 和 Google Sheets 监控并筛选法国采购招标
使用 BOAMP API 和 Google Sheets 监控并筛选法国采购招标
If
Code
Wait
+7
55 节点Growth AI
内容创作
使用OpenAI、RunwayML和ElevenLabs自动化无脸短视频
使用OpenAI、RunwayML和ElevenLabs自动化无脸短视频:从脚本到社交媒体
Set
Code
Wait
+18
56 节点LeeWei
内容创作
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
内容创作