企业网站运行一段时间后,经常会经历模板改版、栏目扩展、页面迁移以及前后端调整。很多搜索问题并不是正文内容本身造成的,而是页面模板中的 Title、Canonical、Robots 或 H1 等基础标签发生了异常。
如果网站页面数量较少,可以直接打开源码逐页查看;但当页面增加到几十甚至几百个之后,人工检查效率会明显下降。
本文以一个本地 HTML 页面目录为例,使用 Python 编写一个简单的 SEO 页面检测脚本,批量检查几个容易出现模板级问题的字段:
页面是否存在 Title;
多个页面是否使用相同 Title;
页面是否存在 Canonical;
Robots 中是否意外出现 noindex;
页面 H1 数量是否异常。
这类脚本更适合部署前检查、模板改版后的回归检查以及静态页面批量排查。
一、测试环境
本文示例环境:
Python 3.13
beautifulsoup4 4.14
HTML5 页面
UTF-8 编码
安装依赖:
pip install beautifulsoup4
测试目录:
seo_demo/
├── index.html
├── about.html
└── seo_check.py
实际项目中,可以将构建后的静态 HTML 页面放到对应目录中,再统一执行检查。
二、准备两个测试页面
首先准备一个相对正常的页面:
<!doctype html>
SEO技术测试
页面正文内容。
然后再准备一个故意存在问题的页面:
<!doctype html>
关于页面
重复H1
第二个页面包含四个比较典型的问题:
与第一个页面使用相同 Title;
没有 Canonical;
Robots 中存在 noindex;
页面出现两个 H1。
这些问题如果只存在于单个页面中并不难发现,但如果来自公共模板,就可能同时影响大量页面。
三、编写批量检测脚本
建立 seo_check.py:
from pathlib import Path
from collections import Counter
from bs4 import BeautifulSoup
ROOT = Path(".")
def scan_page(path):
html = path.read_text(encoding="utf-8")
soup = BeautifulSoup(html, "html.parser")
title = (
soup.title.get_text(strip=True)
if soup.title
else ""
)
canonical_tag = soup.find(
"link",
rel=lambda value:
value and "canonical" in
(value if isinstance(value, list) else [value])
)
canonical = (
canonical_tag.get("href", "").strip()
if canonical_tag
else ""
)
robots_tag = soup.find(
"meta",
attrs={
"name": lambda value:
value and value.lower() == "robots"
}
)
robots = (
robots_tag.get("content", "").strip().lower()
if robots_tag
else ""
)
h1_count = len(soup.find_all("h1"))
issues = []
if not title:
issues.append("missing_title")
if not canonical:
issues.append("missing_canonical")
if "noindex" in robots:
issues.append("noindex")
if h1_count != 1:
issues.append(f"h1_count={h1_count}")
return {
"file": path.name,
"title": title,
"canonical": canonical,
"robots": robots,
"h1_count": h1_count,
"issues": issues
}
pages = [
scan_page(path)
for path in sorted(ROOT.glob("*.html"))
]
title_counter = Counter(
row["title"]
for row in pages
if row["title"]
)
for row in pages:
if (
row["title"]
and title_counter[row["title"]] > 1
):
row["issues"].append("duplicate_title")
for row in pages:
print("=" * 50)
print("文件:", row["file"])
print("Title:", row["title"])
print("Canonical:", row["canonical"])
print("Robots:", row["robots"])
print("H1数量:", row["h1_count"])
print(
"问题:",
", ".join(row["issues"])
if row["issues"]
else "未发现"
)
这个脚本没有尝试给网站计算所谓的“SEO分数”,而是把检查结果拆成具体问题。
这样做有一个实际好处:开发人员拿到结果后,可以直接定位模板或页面配置,而不是面对一个无法解释的综合分数。
四、验证结果
在本文两个测试页面上运行后,正常页面可以识别出:
Canonical:/seo-test
Robots:index,follow
H1数量:1
由于两个测试文件故意使用了同样的 Title,因此脚本还会标记:
duplicate_title
第二个页面则会同时得到:
missing_canonical
noindex
h1_count=2
duplicate_title
这说明检测逻辑已经能够区分不同类型的问题。
五、为什么要把SEO检查放进开发流程
很多 SEO 基础错误其实并不是编辑人员造成的。
例如模板升级时删除了一段 Canonical 输出逻辑,测试环境中的 noindex 配置被带到了正式模板,或者多个栏目共用了同一个 Title 变量。
从开发角度看,这些问题更接近“页面质量回归问题”。
因此,可以进一步把脚本加入构建或部署前的检查流程。例如当发现以下问题时输出警告:
missing_title
missing_canonical
noindex
duplicate_title
如果项目对页面模板要求比较严格,也可以让脚本在发现严重问题时返回非零退出码,使其成为 CI 流程中的一个检查节点。
六、进一步扩展
基础版本完成之后,还可以继续增加:
Description 是否为空;
页面语言属性是否存在;
图片 alt 是否缺失;
页面内部链接是否出现无效路径;
Sitemap 中的页面是否实际存在;
页面是否存在重复 Canonical;
Open Graph 字段是否缺失;
结构化数据 JSON 是否能够正常解析。
需要注意的是,自动脚本更适合发现结构和配置异常,并不能替代对页面内容质量、搜索意图以及信息价值的人工判断。
七、总结
对于页面数量逐渐增加的网站,与其在出现搜索异常后再逐页排查,不如把一部分 SEO 基础规则转化成可以执行的检测逻辑。
Title、Canonical、Robots 和 H1 都属于页面模板层面能够程序化检查的信息。通过简单的 Python 脚本,就可以提前发现重复、缺失和错误配置,为后续页面维护提供更清晰的问题清单。
本文由梓彤超越(武汉)科技有限公司整理。