8
n8n 中文网amn8n.com

使用正则表达式和 AI 发现隐藏的网站 API 端点

高级

这是一个Engineering, AI领域的自动化工作流,包含 58 个节点。主要使用 If, Set, Html, Sort, Merge 等节点,结合人工智能技术实现智能自动化。 使用正则表达式和人工智能发现隐藏的网站API端点

前置要求
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "c5KEf1x6qMsdFPbT",
  "meta": {
    "instanceId": "26b813dbc9e6a5d4d0e9118e36933b8ffd29262f560a7abf71d40736214ae089"
  },
  "name": "使用正则表达式和 AI 发现隐藏的网站 API 端点",
  "tags": [],
  "nodes": [
    {
      "id": "cf0b4351-ccd5-409f-bc96-7ac1ae645b47",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3080,
        1820
      ],
      "parameters": {
        "color": 4,
        "width": 800,
        "height": 520,
        "content": "# 验证工具:AI 代理自我评估并迭代改进"
      },
      "typeVersion": 1
    },
    {
      "id": "d80057fc-912b-4aa1-97df-3ad8e93e168e",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        520
      ],
      "parameters": {
        "color": 6,
        "width": 1540,
        "height": 420,
        "content": "# 1. 使用预定义正则表达式提取 API 端点"
      },
      "typeVersion": 1
    },
    {
      "id": "ba232bb7-8b9f-4ad4-bc10-25c997728c8a",
      "name": "自动修复输出解析器",
      "type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
      "position": [
        3320,
        1500
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "a6d848f2-c1d4-40b2-8f69-55425c6d9843",
      "name": "开始 API 发现",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        980
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1003b136-9567-4498-8113-0ad1726bc41e",
      "name": "配置",
      "type": "n8n-nodes-base.set",
      "position": [
        180,
        980
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d1dde61e-fa30-4c24-a9d0-cd539ee08334",
              "name": "URL",
              "type": "string",
              "value": "<URL of the website i.e. https://example.com>"
            },
            {
              "id": "3536b6ab-3fbc-4a88-81fe-d47920d37a40",
              "name": "User-Agent",
              "type": "string",
              "value": "Mozilla/5.0 (compatible; API-Discovery-Bot/1.0)"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "62735481-3571-4df2-8c3d-afe20a1703b8",
      "name": "获取网站 HTML",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        360,
        980
      ],
      "parameters": {
        "url": "={{ $json.URL }}",
        "options": {
          "timeout": 30000,
          "redirect": {
            "redirect": {}
          },
          "response": {
            "response": {
              "neverError": true
            }
          },
          "allowUnauthorizedCerts": true
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "User-Agent",
              "value": "={{ $json['User-Agent'] }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f72069a0-28ee-42a8-9400-f64601beb609",
      "name": "提取 JS 文件的 URL",
      "type": "n8n-nodes-base.html",
      "position": [
        540,
        980
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "JS URLs",
              "attribute": "src",
              "cssSelector": "script[src]",
              "returnArray": true,
              "returnValue": "attribute"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d1d12617-779b-4afa-b9fb-a9a98870c60f",
      "name": "分离 JS 文件的 URL",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        720,
        980
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "JS URLs"
      },
      "typeVersion": 1
    },
    {
      "id": "794b8871-2fc9-4e46-8eee-6579cbcad8c8",
      "name": "保留相关的 JS 文件",
      "type": "n8n-nodes-base.filter",
      "position": [
        900,
        980
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "78e816c0-78ae-4a5c-a72e-a41ddb20919f",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json['JS URLs'].startsWith('/') || $json['JS URLs'].startsWith('./') }}",
              "rightValue": true
            },
            {
              "id": "46442f81-14e6-4acc-bc90-b49571748a00",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "yimg"
            },
            {
              "id": "7953c6e1-ecec-4590-9620-b61d5a37e311",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "={{ ($('Configuration').first().json.URL).extractDomain() }}"
            },
            {
              "id": "cdac1d00-ee7b-4f70-af95-8fa2f5c8c491",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "/build/"
            },
            {
              "id": "831e432e-eeca-490d-aed0-735b1130f337",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "/dist/"
            },
            {
              "id": "dec40baf-b2a3-4192-9f2a-3f5eeb0b692c",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "bundle"
            },
            {
              "id": "edc77e96-d193-4339-a0b3-1bcf17744b7f",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'].extractDomain() }}",
              "rightValue": "cdn"
            },
            {
              "id": "72295f0a-703f-4050-8d07-9d712db1025e",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "/dist"
            },
            {
              "id": "948da288-7c23-4b62-90e1-7a38ebaed16d",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "/frontend/"
            },
            {
              "id": "89c4bfe0-2fa1-4135-ac16-503db39325e9",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json['JS URLs'] }}",
              "rightValue": "/packages/"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d3aeef5a-98ad-49cc-abc0-6fa8d8f73783",
      "name": "获取 JS 内容",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1080,
        980
      ],
      "parameters": {
        "url": "={{ !!$json['JS URLs'].extractDomain() ? $json['JS URLs'].replace(/^\\/\\//, 'https://') : ($('Configuration').first().json.URL+'/'+$json['JS URLs']).replaceAll(/(?<!:)\\/\\//g,'/').replaceAll(/(?<!:)\\/\\//g,'/') }}",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1
            }
          },
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "30de7d2a-86f7-4de4-92f6-cc9387432407",
      "name": "提取 API 端点",
      "type": "n8n-nodes-base.set",
      "position": [
        1260,
        980
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d7f393c9-7c3c-4cd1-a6f4-d0fdb2ea4876",
              "name": "Endpoints",
              "type": "array",
              "value": "={{ [...$json.data.replace(/\\\\u002[Ff]/g, '/').matchAll(/(?:[\"'`])((?:https?:\\/\\/[^\\/\\s\"'`]+)?\\/[^\\s\"'`]*?)(?:[\"'`])/g)].map(m => m[1].split('?')[0].replace(/\\/\\*+$/, '')).filter(url => url.includes('/') && url.length > 2 && !url.match(/\\.(js|css|png|jpg|gif|svg|ico)$/i)) }}"
            },
            {
              "id": "b8fbc2ff-9d45-41f4-b9bd-902d056ad76b",
              "name": "JS",
              "type": "boolean",
              "value": true
            },
            {
              "id": "063fa794-c1e3-41df-81ec-ff3d5eecabc5",
              "name": "Source",
              "type": "string",
              "value": "={{ $('Split URLs of JS files').item.json['JS URLs'] }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "da398951-fda2-40d3-a38e-e83ae9a9dfeb",
      "name": "检查端点数量",
      "type": "n8n-nodes-base.if",
      "position": [
        1440,
        980
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "9ec79d99-e2c4-47f3-9920-07c00ae10f71",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.Endpoints.length }}",
              "rightValue": 4
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2a4e5d2e-fcac-4f29-b042-0e6287b636c5",
      "name": "分离端点",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1640,
        980
      ],
      "parameters": {
        "include": "selectedOtherFields",
        "options": {},
        "fieldToSplitOut": "Endpoints",
        "fieldsToInclude": "JS, Source"
      },
      "typeVersion": 1
    },
    {
      "id": "53ebcbf7-1ba8-4a98-8a9e-ff73537c4ebe",
      "name": "移除重复项",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        1800,
        980
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "316b5b26-a96a-427f-9d20-8391a1c24bb5",
      "name": "AI 端点分析",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1820,
        1160
      ],
      "parameters": {
        "url": "https://openrouter.ai/api/v1/chat/completions",
        "method": "POST",
        "options": {
          "timeout": 1000000,
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 30000
            }
          }
        },
        "jsonBody": "={\n  \"model\": \"google/gemini-2.5-pro-preview\",\n   \"temperature\": 0.1,\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Here is a JS file of the webseite. Please help me to discover API endpoints of the webseite. Look thouroughly at the provided JS code, identify all API endpoints and create a short summary for each one. Specify the methods for each API endpoint.\"\n    },{\n      \"role\": \"user\",\n      \"content\": {{ JSON.stringify($json.data) }}\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openRouterApi"
      },
      "credentials": {
        "openRouterApi": {
          "id": "r1DY63sclH2QsDBK",
          "name": "OpenRouter account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "0449852b-015a-4e2e-b096-5dceb3c64b6c",
      "name": "添加源元数据",
      "type": "n8n-nodes-base.set",
      "position": [
        2000,
        1160
      ],
      "parameters": {
        "options": {
          "stripBinary": true
        },
        "assignments": {
          "assignments": [
            {
              "id": "6c670b9e-b9be-4c25-a0fa-8cd8cdacc622",
              "name": "Source",
              "type": "string",
              "value": "={{ $('Reference for Source Metadata').item.json.Source }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "c4ef28ed-ff34-41c1-a237-40f1c3a1efba",
      "name": "源元数据参考",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1640,
        1160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "286e733f-a42d-4c87-b253-cff48170e91a",
      "name": "处理每个分析的文件",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1640,
        1480
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "ac9fca2a-6d2e-44ae-b2be-e9aad7f89e9b",
      "name": "格式化 AI 结果",
      "type": "n8n-nodes-base.set",
      "position": [
        1820,
        1480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a787bf2a-85c0-4e93-944d-3acf2d82c1e6",
              "name": "Filename",
              "type": "string",
              "value": "=file{{$node[\"Process Each Analyzed File\"].context[\"currentRunIndex\"].toString().padStart(2, '0');}}.txt"
            },
            {
              "id": "51056f59-befb-4b30-ad3d-41ec0b7b621c",
              "name": "Source",
              "type": "string",
              "value": "={{ $json.Source }}"
            },
            {
              "id": "128467f6-c064-4d6f-9e2f-a427e9dfc73e",
              "name": "choices[0].message.content",
              "type": "string",
              "value": "={{ $json?.choices[0]?.message?.content || $json?.choices[0]?.message?.reasoning }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "682bab5d-036d-40c2-aff7-1d844697517f",
      "name": "准备端点文件",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        2000,
        1480
      ],
      "parameters": {
        "options": {
          "fileName": "={{ $json.Filename }}"
        },
        "operation": "toText",
        "sourceProperty": "choices[0].message.content",
        "binaryPropertyName": "=data"
      },
      "typeVersion": 1.1,
      "alwaysOutputData": true
    },
    {
      "id": "fd93d79e-6477-4cf3-af4a-9d5ddecc3c93",
      "name": "保存端点文件",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        2180,
        1480
      ],
      "parameters": {
        "options": {},
        "fileName": "={{ $binary.data.fileName }}",
        "operation": "write"
      },
      "typeVersion": 1
    },
    {
      "id": "5d04fe81-982c-4e07-826e-48f0afbabde6",
      "name": "传递文件名,无二进制数据",
      "type": "n8n-nodes-base.set",
      "position": [
        2000,
        1340
      ],
      "parameters": {
        "options": {
          "stripBinary": true
        },
        "assignments": {
          "assignments": []
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "019b4248-b5ae-4a66-ba55-e05046e0f0bb",
      "name": "合并 AI 分析与文件名",
      "type": "n8n-nodes-base.merge",
      "position": [
        2320,
        1260
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.1
    },
    {
      "id": "4988dbbb-b73b-409c-90cc-1902115ab760",
      "name": "使用 AI 创建端点正则表达式",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3280,
        1260
      ],
      "parameters": {
        "text": "=Here is the file name: {{ $json.fileName }}\n\nHere is the report:\n~~~~\n{{ $json.choices[0].message.content }}\n~~~~",
        "options": {
          "maxIterations": 4,
          "systemMessage": "You are a helpful assistant. You will receive a report with a description of a hidden API. Your task is to generate a regex in a form of n8n expression. This regex should ONLY extract a clean endpoint URL, mentioned in the source file. Use tool to check the validity of the expression. \n\nSEARCH FOR THESE PATTERNS:\n1. /api/ endpoints: '/api/users', '/api/v1/data'\n2. Versioned paths: '/v1/', '/v2/', '/v3/', '/v9/'  \n3. Combined: '/api/v1/', '/api/v2/', '/api/v9/'\n4. Dynamic construction: '/api/' + version + '/users'\n5. Template literals: `/api/v${version}/data`\n6. Object properties: endpoints.v1.users, api.v2.messages\n\nHere is a regex which extracts endpoints from all report files. Use it as an example:\n\n{{ [...$json.data.replace(/\\\\u002[Ff]/g, '/').matchAll(/(?:[\"'`])((?:https?:\\/\\/[^\\/\\s\"'`]+)?\\/[^\\s\"'`]*?)(?:[\"'`])/g)].map(m => m[1].split('?')[0].replace(/\\/\\*+$/, '')).filter(url => url.includes('/') && url.length > 2 && !url.match(/\\.(js|css|png|jpg|gif|svg|ico)$/i)) }}\n\nGenerate expressions for ALL report files. "
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "e976ce33-d4e7-48a7-9879-1679526cb9f3",
      "name": "正则表达式生成 LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        3160,
        1560
      ],
      "parameters": {
        "model": "anthropic/claude-3.7-sonnet",
        "options": {
          "timeout": 3600000,
          "temperature": 0.2
        }
      },
      "credentials": {
        "openRouterApi": {
          "id": "r1DY63sclH2QsDBK",
          "name": "OpenRouter account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7d8618d9-7b3f-473e-99e9-932c89a0cf8b",
      "name": "验证 LLM 正则表达式",
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [
        3620,
        1480
      ],
      "parameters": {
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}",
          "cachedResultName": "={{ $workflow.id }}"
        },
        "workflowInputs": {
          "value": {
            "Filename": "={{ $fromAI('Filename', `from the user prompt`, 'string') }}",
            "query.n8nexpression": "={{ $fromAI('n8nexpression', `valid n8n expression with regex. example: \\{\\{ $json.data.match([PUT REGEX HERE])\\}\\}`, 'string') }}"
          },
          "schema": [
            {
              "id": "query.n8nexpression",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "query.n8nexpression",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Filename",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Filename",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "query.n8nexpression"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e794bc60-fef9-4c76-bb65-b8438eb80792",
      "name": "解析 AI 正则表达式输出",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        3480,
        1680
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"n8nexpression\": {\n\t\t\t\"type\": \"A valid regex to extract clean API endpoints. Example {{ $json.data.match([PUT REGEX HERE])}}\"\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "55aafb04-4cac-46d7-832e-91b99466f3c3",
      "name": "正则表达式验证开始",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        3140,
        2040
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "query.n8nexpression"
            },
            {
              "name": "Filename"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "e30b3def-09c1-42c8-afbb-c1e0421146fb",
      "name": "加载参考端点",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        3380,
        1940
      ],
      "parameters": {
        "options": {},
        "fileSelector": "={{ $json.Filename }}"
      },
      "typeVersion": 1
    },
    {
      "id": "5ebb63c2-8a99-47f8-8ea4-87ff2aff674b",
      "name": "提取端点文件文本",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        3600,
        1940
      ],
      "parameters": {
        "options": {},
        "operation": "text"
      },
      "typeVersion": 1
    },
    {
      "id": "47e010ce-38f0-4235-966d-ad604d0c079b",
      "name": "合并正则表达式、文件名和参考端点",
      "type": "n8n-nodes-base.merge",
      "position": [
        3400,
        2160
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.1
    },
    {
      "id": "dbb3f828-a4e0-44de-b712-f1e6b8593b9a",
      "name": "评估 LLM 正则表达式",
      "type": "n8n-nodes-base.set",
      "position": [
        3620,
        2160
      ],
      "parameters": {
        "include": "except",
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "08f321e4-1012-48d8-ad6e-ed358cf36375",
              "name": "Evaluation results",
              "type": "string",
              "value": "={{ $evaluateExpression($json['query.n8nexpression']) }}"
            }
          ]
        },
        "excludeFields": "data",
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "3fac22e4-4c2d-4f3e-b644-09ef9904cd26",
      "name": "合并初始 AI 分析与 AI 代理输出",
      "type": "n8n-nodes-base.merge",
      "position": [
        3740,
        1140
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.1
    },
    {
      "id": "188a39a5-be2f-4646-9ff8-b35c676b909b",
      "name": "为正则表达式提取准备数据",
      "type": "n8n-nodes-base.set",
      "position": [
        3940,
        1140
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "dc5f209e-87e7-465f-90b6-2ca2272bb7d1",
              "name": "data",
              "type": "string",
              "value": "={{ $json.choices[0].message.content }}"
            },
            {
              "id": "232536f2-4081-43e8-8650-24d5d72a2187",
              "name": "output.n8nexpression",
              "type": "string",
              "value": "={{ !!$json?.output?.n8nexpression ? $json?.output?.n8nexpression : \"\" }}"
            }
          ]
        },
        "includeFields": "output, fileName, Source",
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "1c8926aa-98da-4868-b917-19bca53520a0",
      "name": "执行 LLM 正则表达式",
      "type": "n8n-nodes-base.set",
      "position": [
        4120,
        1140
      ],
      "parameters": {
        "include": "selected",
        "options": {
          "ignoreConversionErrors": true
        },
        "assignments": {
          "assignments": [
            {
              "id": "d7f393c9-7c3c-4cd1-a6f4-d0fdb2ea4876",
              "name": "Endpoints",
              "type": "array",
              "value": "={{ $evaluateExpression($json.output.n8nexpression) }}"
            },
            {
              "id": "fede8667-f874-4200-a3aa-0ce18cbc52ab",
              "name": "LLM",
              "type": "boolean",
              "value": true
            }
          ]
        },
        "includeFields": "fileName, Source",
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "fc403a6d-8e59-448e-8d31-f576dfacf53f",
      "name": "分离 LLM 提取的端点",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        4300,
        1140
      ],
      "parameters": {
        "include": "selectedOtherFields",
        "options": {},
        "fieldToSplitOut": "Endpoints",
        "fieldsToInclude": "LLM, fileName, Source"
      },
      "typeVersion": 1
    },
    {
      "id": "fe9477cf-7c65-461f-b053-a89b329361e1",
      "name": "移除 LLM 端点重复项",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        4500,
        1140
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "40a6dd8a-2955-40d9-845d-43035ec04364",
      "name": "合并原始端点和 LLM 端点",
      "type": "n8n-nodes-base.merge",
      "position": [
        5000,
        1120
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "joinMode": "keepEverything",
        "fieldsToMatchString": "Endpoints, Source"
      },
      "typeVersion": 3.1
    },
    {
      "id": "87919c16-e0c2-4c60-8e78-4aa9f23736fa",
      "name": "最终合并并丰富文件名",
      "type": "n8n-nodes-base.merge",
      "position": [
        5200,
        1120
      ],
      "parameters": {
        "mode": "combine",
        "options": {
          "clashHandling": {
            "values": {
              "resolveClash": "preferLast",
              "overrideEmpty": true
            }
          },
          "multipleMatches": "all"
        },
        "joinMode": "enrichInput1",
        "fieldsToMatchString": "Source"
      },
      "typeVersion": 3.1
    },
    {
      "id": "c6039111-8f99-40d3-9d84-56674b53e74f",
      "name": "排序合并的端点",
      "type": "n8n-nodes-base.sort",
      "position": [
        5400,
        1120
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "fileName"
            },
            {
              "fieldName": "Endpoints"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2fc96028-979c-4c52-85b1-fd4295e94354",
      "name": "重新排序输出字段",
      "type": "n8n-nodes-base.set",
      "position": [
        5580,
        1120
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "2d87ee3f-59cd-440f-9ad1-81af1db079c5",
              "name": "Endpoints",
              "type": "string",
              "value": "={{ $json.Endpoints }}"
            },
            {
              "id": "f6f00797-2d07-49f1-a2df-e044e82acd9a",
              "name": "JS",
              "type": "string",
              "value": "={{ $json.JS }}"
            },
            {
              "id": "8a5acf2e-f362-4811-95b6-f876dfc6c9d2",
              "name": "Source",
              "type": "string",
              "value": "={{ $json.Source }}"
            },
            {
              "id": "4bf6a24c-c61b-4085-b60c-b7c31a612604",
              "name": "fileName",
              "type": "string",
              "value": "={{ $json.fileName }}"
            },
            {
              "id": "d8f566c0-8d5e-486b-bfb8-a2c36d2271da",
              "name": "LLM",
              "type": "string",
              "value": "={{ $json.LLM }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b44b2577-e937-43ea-bdd5-403070caa50e",
      "name": "导出比较结果到 Excel",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        5760,
        1120
      ],
      "parameters": {
        "options": {
          "fileName": "api_comparison.xlsx",
          "headerRow": true
        },
        "operation": "xlsx"
      },
      "typeVersion": 1.1
    },
    {
      "id": "86dbcf40-3b36-48b7-94e6-ab5267c30ad9",
      "name": "为合并准备源和文件名",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        5200,
        1280
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {
          "removeOtherFields": true
        },
        "fieldsToCompare": "Source, fileName"
      },
      "typeVersion": 2
    },
    {
      "id": "0664e7ae-bcd9-4dde-93db-1572bfaa894e",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 5,
        "width": 1540,
        "height": 520,
        "content": "# 该工作流通过分析 JavaScript 代码,帮助自动发现不提供公共 API 的 Web 平台中隐藏的 API 端点。"
      },
      "typeVersion": 1
    },
    {
      "id": "1cffa311-ac2c-4746-aa2c-0c5194776861",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        20,
        760
      ],
      "parameters": {
        "width": 760,
        "height": 140,
        "content": "## 正则表达式提取所有类似 URL 的字符串,并进行 API 聚焦过滤"
      },
      "typeVersion": 1
    },
    {
      "id": "ceaec55d-5626-4724-b4ec-d5738ad23b57",
      "name": "便签 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        20,
        220
      ],
      "parameters": {
        "width": 760,
        "height": 140,
        "content": "## 该工作流最适合用于:"
      },
      "typeVersion": 1
    },
    {
      "id": "5dc66bb7-3645-4959-a52e-73658f5fa09e",
      "name": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        780,
        220
      ],
      "parameters": {
        "width": 740,
        "height": 140,
        "content": "## 该工作流可能不适合用于:"
      },
      "typeVersion": 1
    },
    {
      "id": "8ad235ab-fdb5-4eee-bc5e-b0be081244ef",
      "name": "便签8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        500,
        380
      ],
      "parameters": {
        "color": 3,
        "width": 580,
        "height": 120,
        "content": "## 要求:"
      },
      "typeVersion": 1
    },
    {
      "id": "05119e49-411f-440a-9765-4ec8e229e8b2",
      "name": "便签 9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2140,
        140
      ],
      "parameters": {
        "width": 1540,
        "height": 800,
        "content": "# 2. AI 支持的 API 端点提取"
      },
      "typeVersion": 1
    },
    {
      "id": "7896a8f2-2914-432c-ac04-856f1555d569",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        460
      ],
      "parameters": {
        "color": 5,
        "width": 700,
        "content": "## 阶段 2. LLM 正则表达式生成"
      },
      "typeVersion": 1
    },
    {
      "id": "7b1d73c9-c7e1-4b75-8f1e-a08fcd76a577",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        640
      ],
      "parameters": {
        "color": 4,
        "width": 700,
        "height": 260,
        "content": "## 阶段 3. LLM 正则表达式验证"
      },
      "typeVersion": 1
    },
    {
      "id": "571233f3-0e25-455b-b7e6-3498721ef6d3",
      "name": "便利贴 10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        240
      ],
      "parameters": {
        "color": 6,
        "width": 700,
        "height": 200,
        "content": "## 阶段 1. 初始 AI 分析"
      },
      "typeVersion": 1
    },
    {
      "id": "ea7dd713-a97d-4a29-86d6-885a3c24a5cf",
      "name": "便利贴 11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3060,
        240
      ],
      "parameters": {
        "color": 3,
        "width": 520,
        "height": 180,
        "content": "## 警告!"
      },
      "typeVersion": 1
    },
    {
      "id": "98bc1708-1617-4104-a66b-dadfec2dc384",
      "name": "便签13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2900,
        740
      ],
      "parameters": {
        "color": 6,
        "width": 760,
        "content": "## 阶段 4. LLM 正则表达式执行"
      },
      "typeVersion": 1
    },
    {
      "id": "99853c4d-20d0-4465-ad6a-c97d1b83cb1e",
      "name": "便签12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5000,
        760
      ],
      "parameters": {
        "color": 3,
        "width": 860,
        "height": 200,
        "content": "# 最终比较"
      },
      "typeVersion": 1
    },
    {
      "id": "1f0f991f-a180-4cc6-8ac7-bb7f16f6b755",
      "name": "便签15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        1160
      ],
      "parameters": {
        "color": 3,
        "width": 1540,
        "height": 500,
        "content": "* https://www.sofaconcerts.org (**Knockout.js 框架**)。一个音乐预订平台,也是此工作流的起点。**Google AI Studio** 模型帮助定义了**最相关的端点**,用于自动化平台与 Slack 之间的预订通信:登录、Cookie 会话扩展、获取完整事件详情、事件 ID 和完整对话历史端点。一个用于将消息发送回平台的端点以及详细的请求格式必须使用**开发者工具控制台中的网络选项卡**进行探索。"
      },
      "typeVersion": 1
    },
    {
      "id": "ff90a549-958d-4596-b9d1-c08ccb5ddefa",
      "name": "便签14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        1160
      ],
      "parameters": {
        "height": 80,
        "content": "# 示例:"
      },
      "typeVersion": 1
    },
    {
      "id": "6e821dac-803f-4ca6-9100-8cd5e42e97f3",
      "name": "端点不足",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1640,
        800
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "89d2f3db-d155-489b-bcf0-459a75fc4feb",
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Fetch Website HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Endpoints": {
      "main": [
        [
          {
            "node": "Remove Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch JS Content": {
      "main": [
        [
          {
            "node": "Extract API Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute LLM Regex": {
      "main": [
        [
          {
            "node": "Split LLM-extracted Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format AI Results": {
      "main": [
        [
          {
            "node": "Prepare Endpoints File(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicates": {
      "main": [
        [
          {
            "node": "Merge Original And LLM Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Website HTML": {
      "main": [
        [
          {
            "node": "Extract URLs of JS files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate LLM Regex": {
      "ai_tool": [
        [
          {
            "node": "Create Endpoints Regex With AI",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Add Source Metadata": {
      "main": [
        [
          {
            "node": "Process Each Analyzed File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge AI Analysis & File Name",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Start API Discovery": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Regex Generation LLM": {
      "ai_languageModel": [
        [
          {
            "node": "Create Endpoints Regex With AI",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Endpoints Analysis": {
      "main": [
        [
          {
            "node": "Add Source Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Endpoints Count": {
      "main": [
        [
          {
            "node": "Split Endpoints",
            "type": "main",
            "index": 0
          },
          {
            "node": "Reference for Source Metadata",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Insufficient Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract API Endpoints": {
      "main": [
        [
          {
            "node": "Check Endpoints Count",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Regex Output": {
      "ai_outputParser": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Reorder Output Fields": {
      "main": [
        [
          {
            "node": "Export Comparison Results To Excel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort Merged Endpoints": {
      "main": [
        [
          {
            "node": "Reorder Output Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keep Relevant JS Files": {
      "main": [
        [
          {
            "node": "Fetch JS Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Regex Validation Start": {
      "main": [
        [
          {
            "node": "Load Reference Endpoints",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Regex, File Name & Reference Endpoints",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Save Endpoints File(s)": {
      "main": [
        [
          {
            "node": "Process Each Analyzed File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split URLs of JS files": {
      "main": [
        [
          {
            "node": "Keep Relevant JS Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract URLs of JS files": {
      "main": [
        [
          {
            "node": "Split URLs of JS files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Reference Endpoints": {
      "main": [
        [
          {
            "node": "Extract Endpoints File Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Auto-fixing Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Create Endpoints Regex With AI",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Pass File Name, No Binary": {
      "main": [
        [
          {
            "node": "Merge AI Analysis & File Name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Endpoints File(s)": {
      "main": [
        [
          {
            "node": "Save Endpoints File(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Each Analyzed File": {
      "main": [
        [
          {
            "node": "Pass File Name, No Binary",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format AI Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Endpoints File Text": {
      "main": [
        [
          {
            "node": "Merge Regex, File Name & Reference Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge AI Analysis & File Name": {
      "main": [
        [
          {
            "node": "Merge Initial AI Analysis & AI Agent Output",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create Endpoints Regex With AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reference for Source Metadata": {
      "main": [
        [
          {
            "node": "AI Endpoints Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split LLM-extracted Endpoints": {
      "main": [
        [
          {
            "node": "Remove LLM Endpoints Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Endpoints Regex With AI": {
      "main": [
        [
          {
            "node": "Merge Initial AI Analysis & AI Agent Output",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Remove LLM Endpoints Duplicates": {
      "main": [
        [
          {
            "node": "Merge Original And LLM Endpoints",
            "type": "main",
            "index": 1
          },
          {
            "node": "Prepare Source & File Name for Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Original And LLM Endpoints": {
      "main": [
        [
          {
            "node": "Final Merge with Enriched File Name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Data for Regex Extraction": {
      "main": [
        [
          {
            "node": "Execute LLM Regex",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Final Merge with Enriched File Name": {
      "main": [
        [
          {
            "node": "Sort Merged Endpoints",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Source & File Name for Merge": {
      "main": [
        [
          {
            "node": "Final Merge with Enriched File Name",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Initial AI Analysis & AI Agent Output": {
      "main": [
        [
          {
            "node": "Prepare Data for Regex Extraction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Regex, File Name & Reference Endpoints": {
      "main": [
        [
          {
            "node": "Evaluate LLM Regex",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 工程, 人工智能

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量58
分类2
节点类型22
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
外部链接
在 n8n.io 查看

分享此工作流