"""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 )