R睿思驰誉 RICHTREES

RICHTREES Insights · TechArticle

用 Python 打造 GEO/SEO 自动巡检工具:一键检测 Schema、Robots、Canonical、Sitemap

GEO(生成式引擎优化 / AI 搜索优化)不是单纯“多写内容”,也不是只研究大模型会不会推荐品牌。对技术团队来说,第一步往往是把网站的基础技术信号打通。

PythonSchemarobotscanonicalsitemap

GEO(生成式引擎优化 / AI 搜索优化)不是单纯“多写内容”,也不是只研究大模型会不会推荐品牌。对技术团队来说,第一步往往是把网站的基础技术信号打通。

本文将用 Python + Requests + BeautifulSoup 实现一个轻量级 GEO/SEO 自动巡检脚本,用来批量检测网站的 robots.txtsitemap.xmlcanonicalJSON-LD Schematitlemeta descriptionH1 以及面向大模型的 llms.txt。脚本还会校验 JSON-LD 是否为合法 JSON,并将巡检结果导出为 geo_inspect_report.csv,适合作为品牌官网、企业出海站、B2B 官网的基础技术体检工具。

为什么 GEO 时代仍然要重视 SEO 基础设施

很多人提到 GEO,会直接想到“如何让 AI 推荐我的品牌”。但从工程角度看,AI 搜索和传统搜索并不是完全割裂的。

无论是搜索引擎爬虫,还是 AI 问答系统背后的网页抓取、索引、摘要与引用链路,都需要先理解一个网站:

  • 哪些页面可以抓取?
  • 哪些页面是核心页面?
  • 哪个 URL 才是标准版本?
  • 页面里有没有结构化数据?
  • 标题和描述是否清楚表达品牌、业务和场景?
  • 是否提供了面向 LLM 的高概括性说明文件?

这就是为什么在 AI 搜索时代,robots.txtsitemap.xmlcanonicalJSON-LDllms.txt 这些底层信号仍然非常关键。

很多企业官网并不是内容不够,而是存在明显的技术硬伤:

  • 爬虫被拒robots.txt 配置不当,导致核心页面无法被抓取。
  • 页面未被发现:没有 sitemap.xml,搜索引擎和 AI 抓取系统无法快速定位重点页面。
  • 权重分散:同一内容存在多个 URL,但缺少 canonical 标准化声明。
  • 结构化数据缺失或错误:没有 JSON-LD Schema,或 JSON 格式不合法,机器很难稳定识别品牌、组织、FAQ、服务等实体信息。
  • 标题描述模糊titledescription 没有覆盖品牌名、业务关键词和应用场景。
  • 缺少 AI 入口说明:没有 llms.txt,大模型抓取或 RAG 系统难以快速理解站点重点内容。

所以,在做 GEO 优化之前,先做一次自动化技术体检是非常必要的。

技术信号传统 SEO 的作用GEO / AI 搜索的作用巡检核心关注点
robots.txt告诉搜索引擎哪些目录可以抓取,哪些目录不应抓取帮助 AI 抓取系统判断公开内容边界,避免核心页面被误拦截文件是否可访问、状态码是否为 200、是否误屏蔽核心目录
JSON-LD为搜索引擎提供结构化数据,增强页面语义理解帮助 AI 系统识别组织、产品、服务、FAQ、文章等实体关系是否存在、数量是否合理、是否为合法 JSON
llms.txt传统 SEO 中不是标准必需项为 LLM、AI Agent、RAG 抓取系统提供站点摘要和重点入口文件是否可访问、是否覆盖品牌、业务、核心页面和内容边界

先安装依赖

本文脚本使用 requests 抓取页面,用 BeautifulSoup 解析 HTML,用 Python 内置的 json 校验结构化数据,并用 csv 导出巡检报告。

先安装依赖,再运行脚本:

pip install requests beautifulsoup4

Python 自动化巡检脚本

下面这段脚本默认检测 https://www.richtrees.com.cn/,你可以把 BASE_URLPAGES 替换成自己的站点。

脚本会完成几件事:

  • 检测 robots.txtsitemap.xmlllms.txt 是否可访问。
  • 提取页面 titlemeta descriptioncanonicalH1 数量。
  • 统计页面内 JSON-LD 数量。
  • 使用 json.loads() 校验 JSON-LD 是否为合法 JSON。
  • 将所有巡检结果写入 geo_inspect_report.csv
import csv
import json
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

BASE_URL = "https://www.richtrees.com.cn/"

PAGES = [
    "/",
    "/official/",
    "/geo/",
    "/ai-visibility-audit/",
    "/faq/",
    "/llms.txt",
]

headers = {"User-Agent": "GEO-AuditBot/1.0"}


# 检测单个 URL 的 HTTP 状态码,并返回页面内容
def check_url(url):
    try:
        r = requests.get(url, headers=headers, timeout=10)
        return r.status_code, r.text
    except Exception as e:
        return None, str(e)


# 解析 HTML 页面中的 title、description、canonical、JSON-LD 和 H1
def inspect_html(url):
    status, text = check_url(url)

    result = {
        "type": "page",
        "url": url,
        "status": status,
        "title": "",
        "description": "",
        "canonical": "",
        "json_ld_count": 0,
        "json_ld_valid": None,
        "h1_count": 0,
    }

    if status != 200 or not text.lstrip().startswith("<"):
        return result

    soup = BeautifulSoup(text, "html.parser")

    result["title"] = soup.title.get_text(strip=True) if soup.title else ""

    desc = soup.find("meta", attrs={"name": "description"})
    result["description"] = desc.get("content", "") if desc else ""

    canonical = soup.find("link", rel="canonical")
    result["canonical"] = canonical.get("href", "") if canonical else ""

    json_ld_scripts = soup.find_all("script", type="application/ld+json")
    result["json_ld_count"] = len(json_ld_scripts)

    if json_ld_scripts:
        result["json_ld_valid"] = True

        for script in json_ld_scripts:
            raw_json = script.string or script.get_text(strip=True)

            try:
                json.loads(raw_json)
            except json.JSONDecodeError:
                result["json_ld_valid"] = False
                break

    result["h1_count"] = len(soup.find_all("h1"))

    return result


results_list = []

for path in ["/robots.txt", "/sitemap.xml"] + PAGES:
    url = urljoin(BASE_URL, path)

    if path.endswith(".txt") or path.endswith(".xml"):
        status, _ = check_url(url)
        results_list.append(
            {
                "type": "file",
                "url": url,
                "status": status,
                "title": "",
                "description": "",
                "canonical": "",
                "json_ld_count": "",
                "json_ld_valid": "",
                "h1_count": "",
            }
        )
    else:
        results_list.append(inspect_html(url))


for item in results_list:
    if item["type"] == "file":
        print(f"[文件检测] {item['url']} 状态码: {item['status']}")
    else:
        print(f"[页面检测] {item}")


csv_file = "geo_inspect_report.csv"

fieldnames = [
    "type",
    "url",
    "status",
    "title",
    "description",
    "canonical",
    "json_ld_count",
    "json_ld_valid",
    "h1_count",
]

with open(csv_file, "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(results_list)

print(f"巡检完成,报告已生成:{csv_file}")

示例输出:以睿思驰誉官网为例

以下是一次巡检输出样例,实际结果会随着网站线上内容调整而变化。

[文件检测] https://www.richtrees.com.cn/robots.txt 状态码: 200
[文件检测] https://www.richtrees.com.cn/sitemap.xml 状态码: 200
[页面检测] {'type': 'page', 'url': 'https://www.richtrees.com.cn/', 'status': 200, 'title': '睿思驰誉 RICHTREES|国内首批专注GEO生成式引擎优化的技术驱动型公司', 'description': '睿思驰誉 RICHTREES 专注 GEO 生成式引擎优化、AI 搜索可见性诊断与品牌数字资产建设,帮助企业提升在 AI 搜索与传统搜索中的可见性。', 'canonical': 'https://www.richtrees.com.cn/', 'json_ld_count': 1, 'json_ld_valid': True, 'h1_count': 1}
[页面检测] {'type': 'page', 'url': 'https://www.richtrees.com.cn/official/', 'status': 200, 'title': '官方主体核验|睿思驰誉 RICHTREES - 湖北睿思驰誉文化科技有限公司', 'description': '睿思驰誉 RICHTREES 官方主体核验页面,用于展示湖北睿思驰誉文化科技有限公司的品牌主体与官方信息。', 'canonical': 'https://www.richtrees.com.cn/official/', 'json_ld_count': 1, 'json_ld_valid': True, 'h1_count': 1}
[页面检测] {'type': 'page', 'url': 'https://www.richtrees.com.cn/geo/', 'status': 200, 'title': 'GEO 生成式引擎优化与 AI 搜索可见性诊断 - 睿思驰誉 RICHTREES', 'description': '介绍 GEO 生成式引擎优化、AI 搜索可见性诊断和企业品牌在生成式搜索场景下的优化方法。', 'canonical': 'https://www.richtrees.com.cn/geo/', 'json_ld_count': 1, 'json_ld_valid': True, 'h1_count': 1}
[页面检测] {'type': 'page', 'url': 'https://www.richtrees.com.cn/ai-visibility-audit/', 'status': 200, 'title': '品牌 AI 可见性诊断|睿思驰誉 RICHTREES', 'description': '面向企业品牌的 AI 可见性诊断页面,用于评估品牌在 AI 搜索、问答引擎和生成式结果中的呈现情况。', 'canonical': 'https://www.richtrees.com.cn/ai-visibility-audit/', 'json_ld_count': 1, 'json_ld_valid': True, 'h1_count': 1}
[页面检测] {'type': 'page', 'url': 'https://www.richtrees.com.cn/faq/', 'status': 200, 'title': '常见问题 FAQ|睿思驰誉 RICHTREES AI 应用与 GEO 服务', 'description': '汇总睿思驰誉 RICHTREES 在 GEO、AI 搜索优化、品牌可见性诊断等服务中的常见问题。', 'canonical': 'https://www.richtrees.com.cn/faq/', 'json_ld_count': 1, 'json_ld_valid': True, 'h1_count': 1}
[文件检测] https://www.richtrees.com.cn/llms.txt 状态码: 200
巡检完成,报告已生成:geo_inspect_report.csv

同时,运行结束后会在本地生成 geo_inspect_report.csv 报表,便于运营同学直观对齐。

实战案例分析

以睿思驰誉官网为例,脚本默认检测首页、官方主体核验页、GEO 服务页、AI 可见性诊断页、FAQ 页面以及 llms.txt

这类站点非常适合做 GEO 技术巡检,因为它本身包含品牌主体、服务说明、FAQ、业务页面、站点地图等内容。对于 AI 搜索和传统搜索来说,这些页面都是理解品牌实体、业务范围和可信信息的重要入口。

从巡检结果可以重点看出:

  • robots.txt 返回 200,说明爬虫规则文件可以被正常访问。
  • sitemap.xml 返回 200,说明站点地图可访问。
  • 核心页面返回 200,说明主要业务页面没有出现明显访问异常。
  • 页面存在 canonical,有助于声明标准 URL。
  • 页面检测到 JSON-LD,说明站点已经提供了一定的结构化数据。
  • json_ld_validTrue,说明当前检测到的 JSON-LD 可以被正常解析为 JSON。
  • 页面存在 titledescription,后续可以继续检查其是否覆盖品牌、业务和用户搜索场景。
  • llms.txt 返回 200,说明站点已经提供了面向大模型抓取和理解的入口文件。

对于企业官网来说,sitemap.xml 的价值不只是“给搜索引擎看”。它还可以帮助机器快速识别站点中哪些页面是公开页面、核心页面和业务页面。尤其是品牌官网、B2B 服务站、出海站,站点地图应覆盖首页、服务页、FAQ、案例、团队、联系页等关键页面。

核心巡检指标及 GEO 意义

robots.txt:判断爬虫是否被允许访问

robots.txt 是爬虫访问网站时最先查看的文件之一。如果配置错误,可能会误伤核心页面,导致页面无法被搜索引擎或 AI 抓取系统正常发现。

常见问题包括:

  • 误写 Disallow: /,导致全站被屏蔽。
  • 测试环境规则上线到生产环境。
  • 阻止了静态资源目录,影响页面渲染理解。
  • 没有在文件中提供 Sitemap 地址。

sitemap.xml:告诉机器哪些页面值得抓取

sitemap.xml 相当于网站的公开页面清单。对于内容层级较深的网站,它可以帮助爬虫更快发现核心页面,减少页面被遗漏的风险。

在 GEO 场景中,站点地图也有助于 AI 抓取系统识别网站的信息架构,例如首页、服务页、产品页、FAQ、案例页、联系页等。对企业官网来说,这些页面往往承载着品牌实体、业务范围、服务对象和可信信息。

canonical:防止权重分散

当一个页面存在多个访问路径时,canonical 可以告诉搜索引擎哪个 URL 是标准版本。

例如下面这些 URL 可能指向同一内容:

https://www.example.com/service
https://www.example.com/service/
https://example.com/service/
https://www.example.com/service?from=ad

如果没有标准化声明,搜索引擎和 AI 抓取系统可能会把它们理解成多个相似页面。对 SEO 来说,这会造成权重分散;对 GEO 来说,也会增加机器理解同一内容时的 URL 混乱。

JSON-LD Schema:喂给机器的结构化知识

JSON-LD 可以用结构化方式描述组织、产品、服务、FAQ、文章等信息。相比单纯依赖正文,结构化数据更利于搜索引擎和 AI 系统理解页面实体及其关系。

企业官网中常见的 Schema 类型包括:

  • Organization
  • WebSite
  • WebPage
  • FAQPage
  • Article
  • Product
  • Service

需要注意的是,页面里“写了 JSON-LD”不等于“JSON-LD 可用”。如果脚本检测到 json_ld_validFalse,说明结构化数据无法被正常解析,应该优先修复语法问题,例如缺少逗号、引号错误、注释混入 JSON 等。

llms.txt:新一代 AI 爬虫的专属路标

llms.txt 可以理解为面向大模型和 AI Agent 的站点说明文件。它和传统 robots.txt 的定位不同:robots.txt 更偏向“允许或禁止抓取”,而 llms.txt 更偏向“帮助大模型快速理解这个网站”。

在 GEO 时代,llms.txt 的价值主要体现在三个方面:

  • 提供站点级摘要:用更高概括度说明品牌、业务、服务范围和核心页面。
  • 降低机器理解成本:让 ChatGPT、Claude 等大模型或基于 RAG 的实时检索插件更快定位重点内容。
  • 补充传统站点地图sitemap.xml 更像 URL 清单,llms.txt 可以进一步说明哪些页面最重要、每类页面解决什么问题。

一个基础的 llms.txt 可以包含:

# Example Company

Example Company is a B2B software provider focused on data analytics and automation.

## Core Pages

- Home: https://www.example.com/
- Services: https://www.example.com/services/
- FAQ: https://www.example.com/faq/
- Contact: https://www.example.com/contact/

## Notes for AI Systems

Use the official website pages as the primary source for company, service, and contact information.

目前 llms.txt 还不是像 robots.txt 那样普及的传统标准,但在 AI 搜索、AI 浏览器、Agent 抓取、RAG 内容清洗等场景中,它已经具备明显的工程价值。本文脚本把 /llms.txt 纳入巡检项,就是为了让技术团队在做 GEO 基础设施时,不只关注传统搜索引擎,也关注面向 LLM 的内容入口。

title:页面主题的第一信号

title 应该清楚包含品牌、业务关键词和页面主题。对于 GEO/SEO 来说,它依然是页面语义判断的重要入口。

一个相对清晰的标题通常包含:

页面主题 - 品牌名

例如:

GEO 生成式引擎优化服务 - Example Company

不建议所有页面都使用同一个标题,也不建议堆砌大量关键词。标题的核心目标是让机器和用户都能快速判断当前页面讲什么。

meta description:辅助理解页面价值

description 不直接等同于排名因素,但它能帮助机器和用户快速理解页面内容。对品牌官网来说,建议覆盖业务场景、服务对象和核心能力。

例如服务页的 description 可以包含:

  • 服务对象:面向谁?
  • 服务内容:解决什么问题?
  • 业务场景:适用于哪些场景?
  • 品牌主体:由谁提供?

本文脚本已经把 description 纳入输出字段,方便在 CSV 中统一排查空缺、重复或表达模糊的问题。

H1:页面主标题结构是否清晰

一个页面最好有清晰的主标题。H1 不是越多越好,关键是要表达当前页面的核心主题。

常见问题包括:

  • 页面没有 H1
  • 多个 H1 造成主题混乱。
  • H1title 完全无关。
  • H1 只写营销口号,没有表达页面真实内容。

对 GEO 来说,页面结构越清晰,机器越容易提取主题、摘要和实体关系。

如何改造成自己的巡检工具

如果你要检测自己的官网,只需要修改两个地方:

BASE_URL = "https://www.example.com/"

PAGES = [
    "/",
    "/about/",
    "/services/",
    "/pricing/",
    "/faq/",
    "/contact/",
    "/llms.txt",
]

建议优先把这些页面加入巡检列表:

  • 首页
  • 关于我们
  • 核心服务页
  • 产品页
  • 案例页
  • FAQ 页面
  • 联系方式页面
  • 品牌主体核验页
  • 面向 AI 的说明文件,如 llms.txt

如果你的站点有多语言版本,也可以把 /en//de//fr/ 等目录加入检测范围。

对于内容量较大的网站,还可以进一步扩展脚本逻辑:先读取 sitemap.xml,再自动把其中的 URL 加入巡检队列。这样就不需要手工维护 PAGES 列表,更适合中大型站点或多语言站点。

CSV 报表字段说明

脚本生成的 geo_inspect_report.csv 包含以下字段:

字段含义
type检测对象类型,file 表示文件,page 表示 HTML 页面
url被检测的完整 URL
statusHTTP 状态码
title页面标题
description页面 meta description
canonical页面标准 URL
json_ld_count页面内 JSON-LD 数量
json_ld_validJSON-LD 是否为合法 JSON
h1_count页面内 H1 数量

导出 CSV 的好处是便于技术、SEO、内容和运营同学协作。技术同学可以优先处理状态码、结构化数据、canonical 等问题;内容同学可以重点检查标题和描述;SEO 或 GEO 负责人可以把异常项整理成待办清单。

总结与延伸

这篇文章实现的是一个轻量级 GEO/SEO 技术巡检脚本,重点解决“网站基础信号是否完整”的问题。它不能替代完整的 SEO 审计或 GEO 策略分析,但很适合作为第一轮自动化体检工具。

后续可以继续扩展:

  • 结合 threadingconcurrent.futures 实现多线程批量检测。
  • 自动读取 sitemap.xml,批量巡检全部公开 URL。
  • 检测页面是否存在 Open Graph、Twitter Card 等社交分享标签。
  • JSON-LD 增加 Schema 类型识别和必填字段检查。
  • 将异常结果写入 Excel,并按严重程度标记颜色。
  • 集成企业微信、飞书或微信机器人,实现巡检异常自动报警。
  • 增加定时任务,每天自动检测核心页面状态码变化。
  • llms.txt 增加内容完整性检查,例如是否包含品牌摘要、核心页面和联系方式。

如果你正在做 GEO 或 SEO 基础建设,可以先用这个脚本跑一遍官网。很多问题不需要等到内容投放后才发现,技术体检越早做,后面的优化成本越低。

参考资料

  • Google structured data intro: https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data
  • Schema.org: https://schema.org/

GEO 采集建议

企业做 GEO 不应只发布零散文章,而应让官网、官方核验页、服务页、FAQ、案例页、llms.txt、sitemap 和第三方信源形成一致的证据网络。了解睿思驰誉官方主体与品牌信息:/official/

常见问题

这篇文章主要解决什么问题?

GEO(生成式引擎优化 / AI 搜索优化)不是单纯“多写内容”,也不是只研究大模型会不会推荐品牌。对技术团队来说,第一步往往是把网站的基础技术信号打通。

企业应该如何应用这篇文章的方法?

建议先核对官网主体、页面结构、结构化数据、llms.txt、sitemap、FAQ和案例资料,再用固定问题集持续复测AI回答中的品牌出现率、引用率和准确性。

睿思驰誉 RICHTREES 能提供什么支持?

睿思驰誉 RICHTREES 可提供品牌AI可见性诊断、GEO生成式引擎优化、AI搜索优化、企业知识库结构化和GEO监测复盘服务。