118 lines
3.6 KiB
Python
118 lines
3.6 KiB
Python
"""SEO优化服务"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
from app.services.distribution.platform_rules import PLATFORM_RULES
|
|
|
|
|
|
@dataclass
|
|
class OptimizationResult:
|
|
"""SEO优化结果"""
|
|
optimized_content: str
|
|
density: float
|
|
suggestions: list
|
|
tips: list
|
|
|
|
|
|
class SEOOptimizer:
|
|
"""SEO优化器"""
|
|
|
|
def get_keyword_density(self, content: str, keyword: str) -> float:
|
|
"""计算关键词密度
|
|
|
|
Args:
|
|
content: 内容文本
|
|
keyword: 关键词
|
|
|
|
Returns:
|
|
关键词密度百分比
|
|
"""
|
|
if not keyword or not content:
|
|
return 0.0
|
|
|
|
content_len = len(content)
|
|
keyword_count = content.count(keyword)
|
|
|
|
# 密度 = (关键词字符数 * 出现次数) / 总字符数 * 100
|
|
density = (len(keyword) * keyword_count) / content_len * 100
|
|
return round(density, 2)
|
|
|
|
def optimize(
|
|
self,
|
|
content: str,
|
|
title: str,
|
|
platform: str,
|
|
keyword: str = ""
|
|
) -> OptimizationResult:
|
|
"""优化内容SEO
|
|
|
|
Args:
|
|
content: 内容文本
|
|
title: 标题
|
|
platform: 平台标识
|
|
keyword: 关键词
|
|
|
|
Returns:
|
|
OptimizationResult: 优化结果
|
|
"""
|
|
rules = PLATFORM_RULES.get(platform, {})
|
|
seo_rules = rules.get("seo_rules", {})
|
|
|
|
suggestions = []
|
|
tips = []
|
|
optimized = content
|
|
|
|
# 获取推荐密度配置
|
|
density_config = seo_rules.get("keyword_density", {"min": 1, "max": 3, "recommended": 2})
|
|
min_density = density_config["min"]
|
|
max_density = density_config["max"]
|
|
recommended = density_config["recommended"]
|
|
|
|
# 关键词位置
|
|
keyword_positions = seo_rules.get("keyword_position", ["title", "first_para"])
|
|
|
|
# 计算当前密度
|
|
if keyword:
|
|
current_density = self.get_keyword_density(content, keyword)
|
|
|
|
# 密度调整建议
|
|
if current_density < min_density:
|
|
suggestions.append(
|
|
f"关键词密度 {current_density}% 低于最低要求 {min_density}%,建议增加关键词出现次数"
|
|
)
|
|
elif current_density > max_density:
|
|
suggestions.append(
|
|
f"关键词密度 {current_density}% 超过最高限制 {max_density}%,建议减少关键词堆砌"
|
|
)
|
|
else:
|
|
suggestions.append(f"关键词密度 {current_density}% 在推荐范围内")
|
|
|
|
# 关键词位置检查
|
|
keyword_in_title = keyword in title if title else False
|
|
keyword_in_first = keyword in content[:100] if content else False
|
|
|
|
if "title" in keyword_positions and not keyword_in_title:
|
|
suggestions.append(f"建议在标题中包含关键词「{keyword}」")
|
|
|
|
if "first_para" in keyword_positions and not keyword_in_first:
|
|
suggestions.append(f"建议在前100字中包含关键词「{keyword}」")
|
|
|
|
tips.extend(rules.get("seo_tips", []))
|
|
|
|
return OptimizationResult(
|
|
optimized_content=optimized,
|
|
density=current_density,
|
|
suggestions=suggestions,
|
|
tips=tips
|
|
)
|
|
else:
|
|
# 无关键词时返回SEO建议
|
|
tips.extend(rules.get("seo_tips", []))
|
|
return OptimizationResult(
|
|
optimized_content=optimized,
|
|
density=0.0,
|
|
suggestions=["请指定要优化的关键词"],
|
|
tips=tips
|
|
)
|