AI PLAY玩法更新持续收录
← 回到更新流

2026-09-24 · 原文发布日

网站 SEO 知识图谱巡检

手动或每周触发后,从种子与 sitemap 抓 URL、去重并按页数分批;逐页下载 HTML,抽 title、meta description、H1、正文和外链。Claude 对每页返回主/次关键词、命名实体和主题分类,流程把页节点以及关键词、实体、链接关系写入 Postgres 六张表;全部完成后查询页面数、唯一关键词、实体、内链和孤儿页,把站点“数字孪生”体检摘要发到 Slack。

原文要点

来源为 n8n 模板库 Oneclick AI Squad 发布的免费 SEO 知识图谱巡检工作流:手动或每周定时触发,按配置的种子 URL、sitemap 地址、页数上限和 Slack 频道启动;抓取 sitemap.xml 解析去重 URL(可限定同域)并分批;逐页下载 HTML,抽取 title、meta description、H1、正文和外链;交 Anthropic Claude 返回主/次关键词、命名实体和主题分类的结构化 JSON;把页面节点及关键词、实体、链接关系写入 Postgres 六张表(seo_pages、seo_keywords、seo_entities、seo_page_keywords、seo_page_entities、seo_page_links,含 ON CONFLICT 键);全部完成后汇总页面数、唯一关键词、实体、内链、孤儿页等统计发 Slack。配置项含 seedUrl、sitemapUrl、maxPages、sameDomainOnly、anthropicModel、slackChannel,Anthropic 用 x-api-key 头认证。

这次做成什么

在自有 n8n+Postgres 环境搭一条迷你站点体检流水线:抓 3 个合成页面→Claude 抽取关键词实体→写入六张表→统计孤儿页并发 Slack,跑通后即可放大到真实站点。原模板未附可下载工作流文件,以下为本站按原文描述独立设计的搭建与演练方案,SQL 和提示词为本站编写,需在 n8n 中实际核对节点配置。

准备什么

  • 一个可用的 Postgres 数据库(本地 Docker 或云实例均可)及 n8n Postgres 凭据
  • Anthropic API 密钥,以 HTTP Header Auth(x-api-key)方式接入;API 调用按 Anthropic 计费页收费
  • Slack 凭据和一个测试频道,用于接收体检摘要
  • 可自建可运行的 n8n 实例,且能访问目标站点或其 sitemap.xml
  • 一个可控的小型测试站点(或本地静态页)作为抓取对象,避免未经授权抓取他人站点

具体怎么做

  1. 建库建表并设置爬取配置

    在 Postgres 执行下方材料中的建表 SQL(六张表及关系表主键)。在 n8n 工作流起始放一个 Manual Trigger(练熟后可换 Schedule Trigger 每周跑),后接 Set 节点写入配置:seedUrl、sitemapUrl、maxPages(练习设 3)、sameDomainOnly(true)、anthropicModel(填你账号可用的 Claude 模型名,以 Anthropic 控制台为准,原文未指定具体型号)、slackChannel。

  2. 解析 sitemap 并对 URL 去重分批

    HTTP Request 节点 GET sitemapUrl 拿到 XML,用 XML 节点转 JSON,再用 Code 节点提取所有 loc 值:去除锚点和尾部斜杠差异后去重,sameDomainOnly 为 true 时过滤掉非种子域名的 URL,最后按 maxPages 截断。输出应是若干 item,每个含一个 url 字段。

  3. 逐页下载 HTML 并抽取页面要素

    对每条 URL 用 HTTP Request 下载 HTML(建议设超时和 User-Agent),后接 HTML 节点分别抽取 title、meta[name=description] 的 content、h1、body 文本和页内所有 a[href]。用 Code 节点把正文截断到约 4000 字符控制 token 消耗,并把相对链接补全为绝对 URL,标注是否同域(同域计入内链统计)。

  4. 调用 Claude 生成结构化关键词与实体

    HTTP Request 节点 POST Anthropic 消息接口,认证用 x-api-key Header Auth,Body 中 system/user 消息使用下方材料中的提示词,要求只返回 JSON(primary_keyword、secondary_keywords、entities、topic)。拿到响应后用 Code 节点 JSON.parse 并校验字段,失败的页面记入 seo_pages 时把 parse_status 标为 failed 而不是中断整批。

  5. 写入六张表并汇总统计发 Slack

    用 Postgres 节点依次执行:upsert seo_pages(ON CONFLICT url);upsert 关键词和实体表取回 id;写入 seo_page_keywords、seo_page_entities 关系;对页内同域链接写 seo_page_links(source_url、target_url)。全部页面处理完后执行统计 SQL(见材料)得到页面数、唯一关键词数、实体数、内链数、孤儿页数(无任何入链的页面),用 Slack 节点把五项指标发成一条摘要消息。

可直接复制的材料

六张表建表 SQL(本站编写)

本站独立编写的表结构,字段按原文列出的六表用途设计;原模板未公开其 DDL,真实部署时如与原模板查询不一致以原模板为准。

CREATE TABLE IF NOT EXISTS seo_pages (
  url TEXT PRIMARY KEY,
  title TEXT,
  meta_description TEXT,
  h1 TEXT,
  topic TEXT,
  parse_status TEXT DEFAULT 'ok',
  crawled_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS seo_keywords (
  id SERIAL PRIMARY KEY,
  keyword TEXT UNIQUE
);
CREATE TABLE IF NOT EXISTS seo_entities (
  id SERIAL PRIMARY KEY,
  entity TEXT UNIQUE
);
CREATE TABLE IF NOT EXISTS seo_page_keywords (
  page_url TEXT REFERENCES seo_pages(url),
  keyword_id INT REFERENCES seo_keywords(id),
  is_primary BOOLEAN DEFAULT false,
  PRIMARY KEY (page_url, keyword_id)
);
CREATE TABLE IF NOT EXISTS seo_page_entities (
  page_url TEXT REFERENCES seo_pages(url),
  entity_id INT REFERENCES seo_entities(id),
  PRIMARY KEY (page_url, entity_id)
);
CREATE TABLE IF NOT EXISTS seo_page_links (
  source_url TEXT,
  target_url TEXT,
  PRIMARY KEY (source_url, target_url)
);

Claude 页面分析提示词(本站编写)

本站独立编写的提示词;表达式路径需与上游节点输出对齐,非原作者模板内容。

你是 SEO 分析助手。根据下面的网页信息,只输出一个 JSON 对象,不要输出 markdown 代码块或解释文字。

网页标题:{{ $json.title }}
Meta 描述:{{ $json.meta_description }}
H1:{{ $json.h1 }}
正文摘录:{{ $json.body_excerpt }}

输出字段:
- primary_keyword:一个最能代表本页主题的中文或英文关键词短语
- secondary_keywords:至多 3 个次要关键词的数组
- entities:页面中出现的命名实体数组,每项为 {"name": 实体名, "type": "person|organization|product|place|other"}
- topic:一个主题分类,从「产品介绍/教程文档/博客文章/公司信息/其他」中选择

若正文为空或无法理解,primary_keyword 填 null,其余填空数组。

体检统计 SQL(本站编写)

本站编写的汇总查询;孤儿页定义为没有任何被抓取页面指向它的入链,种子页若无人链接也会被计入,解读时注意。

SELECT
  (SELECT count(*) FROM seo_pages) AS pages,
  (SELECT count(*) FROM seo_keywords) AS unique_keywords,
  (SELECT count(*) FROM seo_entities) AS entities,
  (SELECT count(*) FROM seo_page_links) AS internal_links,
  (SELECT count(*) FROM seo_pages p
   WHERE NOT EXISTS (
     SELECT 1 FROM seo_page_links l WHERE l.target_url = p.url
   )) AS orphan_pages;

输入与输出示例

本站虚构演示,数字为按输入设定推导的示意结果,非实测原模板输出;真实站点数字取决于实际抓取。

输入

练习配置:seedUrl=https://demo-site.example、sitemapUrl 同域 /sitemap.xml、maxPages=3、sameDomainOnly=true、sitemap 内含 /、/pricing、/docs/getting-started 三个 URL;其中 /docs/getting-started 页面没有任何其他页面链接到它。

对应输出

三页处理完成后统计 SQL 返回:pages=3, unique_keywords=7, entities=5, internal_links=2, orphan_pages=1。Slack 摘要消息:「站点体检完成:抓取 3 页,唯一关键词 7 个,实体 5 个,内链 2 条,孤儿页 1 个(/docs/getting-started 无入链,建议在首页或定价页加入口)。」

做完检查这些

  • sitemap 中含重复 URL(仅尾部斜杠不同)时去重后只保留一条进入抓取队列
  • sameDomainOnly=true 时 sitemap 里的外域 URL 被过滤,不进入 seo_pages
  • Claude 返回非 JSON 的页面被标记 parse_status=failed,且后续页面仍正常处理不中断
  • 重复运行同一站点时 ON CONFLICT/UNIQUE 约束生效,关键词和实体表不产生重复行
  • 孤儿页统计正确:人为构造的无入链页面出现在 orphan_pages 计数中

容易卡住的地方

  • Anthropic 按 token 计费,正文不截断直接送 Claude 会让大站点成本失控,务必先截断并限制 maxPages
  • 抓取他人站点前确认 robots 协议与授权;建议先在自有的测试站点演练
  • 原模板要求 Anthropic 用 x-api-key 头认证,配置成 Bearer 会得到 401;模型名需与你账号开通的 Claude 型号一致,原文未指定具体型号
  • 六张表的 ON CONFLICT 键若未按查询要求建好,upsert 会报错或产生重复数据;本文 DDL 为本站编写,与原模板内部结构未必完全一致
  • 相对链接不补全为绝对 URL 会导致内链统计和孤儿页判断出错
  • 每周定时触发时若站点临时宕机,建议给 HTTP 节点加重试和错误分支,否则整批失败

原文与作者资料 ↗

本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。

原文标题
Build an SEO knowledge graph digital twin with Claude, Postgres, and Slack
原作者
Oneclick AI Squad
原始发布日期
2026-09-24T04:21:11.144Z
来源
https://n8n.io/workflows/19873