SEO写作与内容优化技巧
好的 SEO 写作不是为机器堆砌关键词,而是让搜索引擎理解你写给人类的内容。
内容优化框架
graph TD
INTENT[搜索意图分析] --> OUTLINE[大纲规划]
OUTLINE --> WRITE[写作执行]
WRITE --> OPTIMIZE[SEO优化]
OPTIMIZE --> REVIEW[质量审核]
REVIEW --> PUBLISH[发布上线]
OPTIMIZE --> KW[关键词密度]
OPTIMIZE --> SEMANTIC[语义丰富度]
OPTIMIZE --> STRUCT[结构标记]
OPTIMIZE --> SNIPPET[精选摘要优化]
style INTENT fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
style OPTIMIZE fill:#c8e6c9,stroke:#388e3c,stroke-width:2px
内容评分系统
"""
SEO 内容质量评分器
"""
from dataclasses import dataclass, field
import re
@dataclass
class ContentAnalysis:
title: str
content: str
target_keyword: str
meta_description: str = ""
word_count: int = 0
def __post_init__(self):
self.word_count = len(self.content.split())
class SEOContentScorer:
"""内容 SEO 质量评分"""
WEIGHTS = {
"keyword_in_title": 15,
"keyword_in_first_100": 10,
"keyword_density": 15,
"word_count": 10,
"heading_structure": 10,
"semantic_terms": 15,
"meta_description": 10,
"readability": 15,
}
@classmethod
def score(cls, ca: ContentAnalysis) -> dict:
scores = {}
kw = ca.target_keyword.lower()
content_lower = ca.content.lower()
title_lower = ca.title.lower()
# 关键词在标题中
scores["keyword_in_title"] = cls.WEIGHTS["keyword_in_title"] if kw in title_lower else 0
# 关键词在前 100 字
first_100 = " ".join(ca.content.split()[:100]).lower()
scores["keyword_in_first_100"] = cls.WEIGHTS["keyword_in_first_100"] if kw in first_100 else 0
# 关键词密度 (理想 0.5–2%)
kw_count = content_lower.count(kw)
density = (kw_count / ca.word_count * 100) if ca.word_count else 0
if 0.5 <= density <= 2.0:
scores["keyword_density"] = cls.WEIGHTS["keyword_density"]
elif 0.2 <= density <= 3.0:
scores["keyword_density"] = cls.WEIGHTS["keyword_density"] // 2
else:
scores["keyword_density"] = 0
# 字数(理想 1000+)
if ca.word_count >= 1500:
scores["word_count"] = cls.WEIGHTS["word_count"]
elif ca.word_count >= 800:
scores["word_count"] = cls.WEIGHTS["word_count"] * 3 // 4
elif ca.word_count >= 400:
scores["word_count"] = cls.WEIGHTS["word_count"] // 2
else:
scores["word_count"] = 0
# 标题结构(H2/H3 数量)
h2_count = ca.content.count("## ")
h3_count = ca.content.count("### ")
if h2_count >= 3 and h3_count >= 2:
scores["heading_structure"] = cls.WEIGHTS["heading_structure"]
elif h2_count >= 2:
scores["heading_structure"] = cls.WEIGHTS["heading_structure"] * 3 // 4
else:
scores["heading_structure"] = cls.WEIGHTS["heading_structure"] // 4
# 语义丰富度(相关词出现)
semantic_score = 0
# 简化演示:检测通用语义指标词
indicators = ["because", "however", "therefore", "example", "compare",
"因为", "然而", "因此", "例如", "比较"]
for ind in indicators:
if ind in content_lower:
semantic_score += 1
scores["semantic_terms"] = min(semantic_score * 3, cls.WEIGHTS["semantic_terms"])
# Meta description
if 50 <= len(ca.meta_description) <= 160:
scores["meta_description"] = cls.WEIGHTS["meta_description"]
elif ca.meta_description:
scores["meta_description"] = cls.WEIGHTS["meta_description"] // 2
else:
scores["meta_description"] = 0
# 可读性(平均句子长度)
sentences = re.split(r"[.!?。!?]", ca.content)
avg_len = sum(len(s.split()) for s in sentences if s.strip()) / max(len(sentences), 1)
if avg_len <= 20:
scores["readability"] = cls.WEIGHTS["readability"]
elif avg_len <= 30:
scores["readability"] = cls.WEIGHTS["readability"] * 2 // 3
else:
scores["readability"] = cls.WEIGHTS["readability"] // 3
total = sum(scores.values())
return {
"总分": f"{total}/100",
"评级": "优秀 ✅" if total >= 80 else "良好 ⚠️" if total >= 60 else "需改进 ❌",
"分项得分": scores,
"关键词密度": f"{density:.2f}%",
"字数": ca.word_count,
}
@staticmethod
def improvement_tips(result: dict) -> list[str]:
"""根据得分给出改进建议"""
tips = []
scores = result["分项得分"]
if scores.get("keyword_in_title", 0) == 0:
tips.append("⚠️ 将目标关键词加入 H1 标题")
if scores.get("keyword_density", 0) == 0:
tips.append("⚠️ 调整关键词密度至 0.5–2% 区间")
if scores.get("word_count", 0) < 8:
tips.append("⚠️ 扩充内容至 1500 词以上以提升权威性")
if scores.get("heading_structure", 0) < 8:
tips.append("⚠️ 增加 H2/H3 小标题,改善扫读体验")
if scores.get("meta_description", 0) == 0:
tips.append("⚠️ 撰写 50–160 字的 Meta Description")
return tips or ["✅ 内容优化状态良好"]
# 演示
sample = ContentAnalysis(
title="如何选择最适合的咖啡豆品种 — 完整购买指南",
content="""## 咖啡豆品种对比
选择咖啡豆时,因为产地和处理方式不同,风味差异极大。然而,大多数人只关注价格。
### 阿拉比卡 vs 罗布斯塔
阿拉比卡豆占全球产量 60%,风味复杂。例如,埃塞俄比亚豆有明显花果香。
比较两者时,罗布斯塔咖啡因含量更高但酸度低。因此,Espresso 拼配常用罗布斯塔。
## 处理方式的影响
### 日晒处理
日晒处理保留更多甜感,然而需要干燥气候配合。
### 水洗处理
水洗处理风味干净,因此精品咖啡店偏爱水洗豆。
## 烘焙程度选择
浅烘焙保留产地风味,深烘焙苦感更重。例如,意式浓缩通常使用深烘豆。
## 如何购买
比较不同渠道时需关注烘焙日期,因为新鲜烘焙的风味更好。
""" * 3,
target_keyword="咖啡豆",
meta_description="完整的咖啡豆购买指南,涵盖品种、处理方式和烘焙程度选择,帮助你找到最适合自己口味的咖啡豆。",
)
scorer = SEOContentScorer()
result = scorer.score(sample)
print("=== SEO 内容质量评分 ===")
print(f" 总分: {result['总分']} {result['评级']}")
print(f" 字数: {result['字数']} 关键词密度: {result['关键词密度']}")
print("\n分项得分:")
for item, score in result["分项得分"].items():
bar = "█" * score + "░" * (SEOContentScorer.WEIGHTS.get(item, 15) - score)
print(f" {item:20s}: {score:3d} {bar}")
print("\n改进建议:")
for tip in scorer.improvement_tips(result):
print(f" {tip}")
标题写作公式
| 类型 | 公式 | 示例 |
|---|---|---|
| 数字列表 | N个[目标]的[方法] | 7个提升转化率的着陆页技巧 |
| 终极指南 | [关键词]完整指南(2024) | 独立站SEO完整指南(2024) |
| 怎么做 | 如何[实现目标]([修饰语]) | 如何在30天内获得1000次点击 |
| 对比型 | [A] vs [B]:哪个更适合[场景] | Shopify vs WooCommerce:独立站首选 |
| 问答型 | [关键词]是什么?[X]点全解析 | Core Web Vitals是什么?4点全解析 |
精选摘要格式优化
| 摘要类型 | 触发信号 | 格式要求 |
|---|---|---|
| 段落摘要 | "什么是X" "X的定义" | 40–60字简洁定义段落 |
| 列表摘要 | "X的步骤" "X的方法" | 有序/无序列表 6–8条 |
| 表格摘要 | "X对比" "X价格" | Markdown表格,3列以内 |
| 视频摘要 | "如何做X" | 带时间戳的视频内容 |
行动清单
- [ ] 用内容评分器对现有 10 篇文章评分,识别得分低于 60 的改进候选
- [ ] 为每篇文章检查 Meta Description:长度 50–160 字,包含目标关键词
- [ ] 审核 H1/H2/H3 层级结构:每篇至少 3 个 H2,关键 H2 含目标词
- [ ] 在每篇文章的前 100 词内自然放置目标关键词
- [ ] 针对"如何/什么是"类意图关键词,添加简洁答案段落争取精选摘要
- [ ] 建立写作模板库:数字列表、终极指南、对比型 3 种标题格式各准备 5 个变体
下一节:03-内容审计与更新策略 — 系统化盘点存量内容,找出可快速提升排名的更新机会。