本页内容
对一个 500 页的站点手动做一次技术 SEO 审计需要 6 到 8 小时。检查 meta 标签、校验标题层级、查找失效链接、分析内容质量——这是一项繁琐又容易出错的工作,大多数团队顶多每季度做一次(Google 自家的 Lighthouse 审计工具有帮助,但无法扩展到全站爬取)。等你做完,一半的问题早已让你丢掉了排名。
CrawlForge 把一整天的 SEO 审计变成 15 分钟的自动化工作流。本指南将向你展示如何构建一个完整的 SEO 审计 pipeline,对站点上的每个页面检查 20 多项排名因素,并生成一份按优先级排序的行动报告。
目录
- 这次 SEO 审计涵盖什么
- 架构总览
- 步骤 1:爬取并映射你的站点
- 步骤 2:提取并校验元数据
- 步骤 3:分析内容质量
- 步骤 4:检查链接与站点结构
- 步骤 5:生成审计报告
- credits 成本分析
- 结果与收益
- 常见问题
这次 SEO 审计涵盖什么
这套自动化审计会检查最具影响力的技术 SEO 因素:
| 类别 | 检查项 | 影响 |
|---|---|---|
| Meta 标签 | 标题长度、描述、Open Graph、canonical | 高 |
| 内容 | 字数、标题层级、关键词密度 | 高 |
| 链接 | 失效链接、孤立页面、重定向链 | 中 |
| 结构 | 站点地图覆盖率、爬取深度、URL 模式 | 中 |
| 性能 | 页面体积、响应时间、阻塞渲染的资源 | 中 |
什么是技术 SEO 审计?它是对一个网站影响搜索引擎爬取、索引和排名的技术健康因素进行系统性审查。与关注你写什么的内容审计不同,技术审计关注搜索引擎如何发现和处理你的页面——包括 Core Web Vitals 和正确的 robots.txt 配置等信号。
架构总览
该审计 pipeline 使用五个 CrawlForge 工具:
| 步骤 | 工具 | Credits | 用途 |
|---|---|---|---|
| 站点发现 | map_site | 3 | 生成完整的 URL 清单 |
| 深度爬取 | crawl_deep | 5 | 遍历站点结构并发现问题 |
| 元数据检查 | extract_metadata | 1 | 逐页校验 meta 标签 |
| 内容分析 | analyze_content | 3 | 为内容质量与可读性评分 |
| 链接审计 | extract_links | 1 | 查找失效链接与孤立链接 |
步骤 1:爬取并映射你的站点
先为站点上的每个页面建立一份完整清单。
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
const client = new Client({
name: 'seo-auditor',
version: '1.0.0',
});
interface SiteAuditConfig {
url: string;
maxPages: number;
maxDepth: number;
}
async function crawlSite(config: SiteAuditConfig) {
// First, get the sitemap for a complete URL list
const siteMap = await client.callTool({
name: 'map_site',
arguments: {
url: config.url,
max_urls: config.maxPages,
include_sitemap: true,
include_metadata: true,
group_by_path: true,
},
});
const mapResult = JSON.parse(siteMap.content[0].text);
// Then crawl to discover pages not in the sitemap
const crawlResult = await client.callTool({
name: 'crawl_deep',
arguments: {
url: config.url,
max_pages: config.maxPages,
max_depth: config.maxDepth,
extract_content: true,
respect_robots: true,
},
});
const crawled = JSON.parse(crawlResult.content[0].text);
// Combine and deduplicate
const allUrls = new Set([
...mapResult.urls,
...crawled.pages.map((p: { url: string }) => p.url),
]);
// Flag pages in crawl but missing from sitemap
const missingFromSitemap = crawled.pages
.filter((p: { url: string }) => !mapResult.urls.includes(p.url))
.map((p: { url: string }) => p.url);
return {
totalPages: allUrls.size,
urls: Array.from(allUrls),
missingFromSitemap,
crawlDepthDistribution: crawled.depthDistribution,
};
}这一步会识别孤立页面(可被爬取但不在你的站点地图中),并给出一份深度分布,显示到达每个页面需要点击多少次。
步骤 2:提取并校验元数据
检查每个页面是否存在有损排名的 meta 标签问题。
interface MetaIssue {
url: string;
type: 'error' | 'warning';
message: string;
}
async function auditMetadata(urls: string[]): Promise<MetaIssue[]> {
const issues: MetaIssue[] = [];
// Batch process metadata extraction
const batchResult = await client.callTool({
name: 'batch_scrape',
arguments: {
urls: urls.map(url => ({ url })),
includeMetadata: true,
maxConcurrency: 15,
},
});
const results = JSON.parse(batchResult.content[0].text);
for (const page of results.results) {
const meta = page.metadata;
const url = page.url;
// Title checks
if (!meta?.title) {
issues.push({ url, type: 'error', message: 'Missing title tag' });
} else if (meta.title.length > 60) {
issues.push({ url, type: 'warning', message: `Title too long (${meta.title.length} chars, max 60)` });
} else if (meta.title.length < 30) {
issues.push({ url, type: 'warning', message: `Title too short (${meta.title.length} chars, min 30)` });
}
// Description checks
if (!meta?.description) {
issues.push({ url, type: 'error', message: 'Missing meta description' });
} else if (meta.description.length > 155) {
issues.push({ url, type: 'warning', message: `Description too long (${meta.description.length} chars)` });
}
// Open Graph checks
if (!meta?.ogTitle) {
issues.push({ url, type: 'warning', message: 'Missing og:title' });
}
if (!meta?.ogImage) {
issues.push({ url, type: 'warning', message: 'Missing og:image' });
}
// Canonical check
if (!meta?.canonical) {
issues.push({ url, type: 'warning', message: 'Missing canonical URL' });
}
}
return issues;
}步骤 3:分析内容质量
使用 analyze_content 为你最重要的页面的可读性、关键词呈现和内容深度评分。
interface ContentScore {
url: string;
wordCount: number;
readabilityScore: number;
topTopics: string[];
sentiment: string;
issues: string[];
}
async function analyzePageContent(url: string): Promise<ContentScore> {
// First extract clean content
const content = await client.callTool({
name: 'extract_content',
arguments: { url },
});
const extracted = JSON.parse(content.content[0].text);
// Then analyze it
const analysis = await client.callTool({
name: 'analyze_content',
arguments: {
text: extracted.content,
},
});
const result = JSON.parse(analysis.content[0].text);
const issues: string[] = [];
// Flag thin content (under 300 words)
if (result.wordCount < 300) {
issues.push(`Thin content: only ${result.wordCount} words (recommend 800+)`);
}
// Flag low readability
if (result.readabilityScore < 40) {
issues.push('Content may be too complex for general audience');
}
return {
url,
wordCount: result.wordCount,
readabilityScore: result.readabilityScore,
topTopics: result.topics || [],
sentiment: result.sentiment || 'neutral',
issues,
};
}步骤 4:检查链接与站点结构
失效链接同时损害用户体验和 SEO。提取所有链接并验证它们能否正确解析。
interface LinkIssue {
sourceUrl: string;
targetUrl: string;
type: 'broken' | 'redirect' | 'external-nofollow';
statusCode?: number;
}
async function auditLinks(urls: string[]): Promise<LinkIssue[]> {
const issues: LinkIssue[] = [];
for (const url of urls) {
const linksResult = await client.callTool({
name: 'extract_links',
arguments: {
url,
base_url: urls[0], // Use site root as base
},
});
const links = JSON.parse(linksResult.content[0].text);
// Check each internal link
for (const link of links.internal || []) {
try {
const check = await client.callTool({
name: 'fetch_url',
arguments: { url: link.href, timeout: 5000 },
});
const response = JSON.parse(check.content[0].text);
if (response.statusCode >= 400) {
issues.push({
sourceUrl: url,
targetUrl: link.href,
type: 'broken',
statusCode: response.statusCode,
});
} else if (response.statusCode >= 300) {
issues.push({
sourceUrl: url,
targetUrl: link.href,
type: 'redirect',
statusCode: response.statusCode,
});
}
} catch {
issues.push({
sourceUrl: url,
targetUrl: link.href,
type: 'broken',
});
}
}
}
return issues;
}步骤 5:生成审计报告
把所有发现汇总进一份按优先级排序的报告。
interface SEOAuditReport {
siteUrl: string;
auditDate: string;
totalPages: number;
overallScore: number;
criticalIssues: number;
warnings: number;
sections: {
metadata: MetaIssue[];
content: ContentScore[];
links: LinkIssue[];
sitemapGaps: string[];
};
}
async function generateReport(siteUrl: string): Promise<SEOAuditReport> {
// Run all audit steps
const site = await crawlSite({
url: siteUrl,
maxPages: 200,
maxDepth: 4,
});
const metaIssues = await auditMetadata(site.urls);
const linkIssues = await auditLinks(site.urls.slice(0, 50)); // Top 50 pages
// Analyze top pages by importance
const topPages = site.urls.slice(0, 20);
const contentScores: ContentScore[] = [];
for (const url of topPages) {
contentScores.push(await analyzePageContent(url));
}
const criticalCount = metaIssues.filter(i => i.type === 'error').length
+ linkIssues.filter(i => i.type === 'broken').length;
const warningCount = metaIssues.filter(i => i.type === 'warning').length
+ contentScores.reduce((sum, s) => sum + s.issues.length, 0);
// Score: start at 100, deduct for issues
const score = Math.max(0, 100 - (criticalCount * 5) - (warningCount * 2));
return {
siteUrl,
auditDate: new Date().toISOString(),
totalPages: site.totalPages,
overallScore: score,
criticalIssues: criticalCount,
warnings: warningCount,
sections: {
metadata: metaIssues,
content: contentScores,
links: linkIssues,
sitemapGaps: site.missingFromSitemap,
},
};
}credits 成本分析
针对一次 200 页的站点审计:
| 操作 | 工具 | Credits | 数量 | 小计 |
|---|---|---|---|---|
| 站点映射 | map_site | 3 | 1 | 3 |
| 深度爬取 | crawl_deep | 5 | 1 | 5 |
| 元数据(批量) | batch_scrape | 5 | 4 批 | 20 |
| 内容分析 | analyze_content | 3 | 20 页 | 60 |
| 内容提取 | extract_content | 2 | 20 页 | 40 |
| 链接提取 | extract_links | 1 | 50 页 | 50 |
| 链接验证 | fetch_url | 1 | 200 次检查 | 200 |
| 每次审计合计 | 378 credits |
每月运行一次审计大约花费 378 credits——远在 Hobby 套餐每月 3,000 credits 的额度之内。Free 套餐(1,000 credits)可覆盖 2-3 次完整审计。
结果与收益
用 CrawlForge 做自动化 SEO 审计能带来:
- 速度:用 15 分钟而非 8 小时完成 200 页的审计
- 一致性:每次都做相同的检查,不存在人工疏漏
- 频率:在不增加成本的情况下,从季度审计转为每周审计
- 优先排序:问题按严重程度排序,让你先修复最要紧的
根据 Ahrefs 关于技术 SEO 影响的研究,使用自动化 SEO 审计的团队通常在 3 个月内技术 SEO 分数提升 15-25%。
常见问题
这与 Screaming Frog 这类付费 SEO 审计工具相比如何?
CrawlForge 的审计 pipeline 更灵活,因为你能精确控制检查什么以及如何为问题评分。Screaming Frog 这类工具的桌面许可证每年 $259,而 CrawlForge 的 credit 模式让你按需运行审计。CrawlForge 最适合想要可编程、与 AI 集成的 SEO 工作流,而非图形界面工具的团队。
我能让审计自动定时运行吗?
可以。把 generateReport 函数封装进一个 cron job 或 serverless 函数(Vercel Cron、AWS Lambda),按你偏好的计划触发它。对大多数站点而言,每周审计是最佳频率。
JavaScript 渲染的页面怎么办?
CrawlForge 会自动处理 JavaScript 渲染。对于需要交互的页面(点击标签页、展开区块),使用 scrape_with_actions 在分析前渲染出完整内容。
今天就开始审计你的站点。 领取 1,000 个免费 credits——足以完成 2-3 次完整的站点审计。无需信用卡。
相关资源:
亲自试一试——无需注册
在 Playground 中运行 CrawlForge 的 27 个抓取与提取工具中的任意一个,然后免费开始,获取 1,000 credits。
1,000 免费 credits • 每月补充 • 无需信用卡
标签
及时获取最新洞察
将教程、产品更新与 Web 抓取技巧直接发送到你的收件箱。
拒绝垃圾邮件,随时可取消订阅。