Coverage for src / keyword_research / analyzer.py: 98%

44 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-13 20:29 +0800

1"""关键词分析器. 

2 

3提供关键词竞争度和价值分析功能。 

4""" 

5 

6from __future__ import annotations 

7 

8from dataclasses import dataclass 

9from typing import TYPE_CHECKING 

10 

11if TYPE_CHECKING: 

12 from src.keyword_research.google_planner import KeywordData 

13 

14 

15@dataclass 

16class KeywordScore: 

17 """关键词评分结果. 

18 

19 Attributes: 

20 keyword: 关键词 

21 search_volume_score: 搜索量得分 (0-100) 

22 competition_score: 竞争度得分 (0-100,越高越好) 

23 value_score: 综合价值得分 (0-100) 

24 overall_score: 总体得分 (0-100) 

25 recommendation: 推荐等级 (high, medium, low) 

26 """ 

27 

28 keyword: str 

29 search_volume_score: float 

30 competition_score: float 

31 value_score: float 

32 overall_score: float 

33 recommendation: str 

34 

35 

36class KeywordAnalyzer: 

37 """关键词竞争度和价值分析器.""" 

38 

39 def __init__(self) -> None: 

40 """初始化分析器.""" 

41 self.volume_weights = { 

42 "very_high": (10000, 100), 

43 "high": (1000, 80), 

44 "medium": (100, 60), 

45 "low": (10, 40), 

46 "very_low": (0, 20), 

47 } 

48 

49 def calculate_volume_score(self, avg_monthly_searches: int) -> float: 

50 """计算搜索量得分.""" 

51 for _tier, (threshold, score) in sorted( 

52 self.volume_weights.items(), 

53 key=lambda x: x[1][0], 

54 reverse=True, 

55 ): 

56 if avg_monthly_searches >= threshold: 

57 return float(score) 

58 return 0.0 

59 

60 def calculate_competition_score(self, competition: str, cpc: float) -> float: 

61 """计算竞争度得分(越高竞争越好).""" 

62 competition_map = {"LOW": 80, "MEDIUM": 50, "HIGH": 20} 

63 base_score = competition_map.get(competition.upper(), 50) 

64 

65 # CPC 调整 

66 if cpc < 1.0: 

67 cpc_adjustment = 10 

68 elif cpc < 3.0: 

69 cpc_adjustment = 0 

70 else: 

71 cpc_adjustment = -10 

72 

73 return max(0, min(100, base_score + cpc_adjustment)) 

74 

75 def calculate_value_score( 

76 self, volume_score: float, competition_score: float, cpc: float 

77 ) -> float: 

78 """计算综合价值得分.""" 

79 base_value = volume_score * 0.4 + competition_score * 0.4 

80 cpc_value = min(20, cpc * 5) 

81 return min(100, base_value + cpc_value) 

82 

83 def analyze(self, data: KeywordData) -> KeywordScore: 

84 """分析单个关键词.""" 

85 avg_cpc = (data.low_cpc + data.high_cpc) / 2 

86 

87 volume_score = self.calculate_volume_score(data.avg_monthly_searches) 

88 competition_score = self.calculate_competition_score(data.competition, avg_cpc) 

89 value_score = self.calculate_value_score(volume_score, competition_score, avg_cpc) 

90 

91 overall_score = volume_score * 0.3 + competition_score * 0.3 + value_score * 0.4 

92 

93 if overall_score >= 70: 

94 recommendation = "high" 

95 elif overall_score >= 50: 

96 recommendation = "medium" 

97 else: 

98 recommendation = "low" 

99 

100 return KeywordScore( 

101 keyword=data.keyword, 

102 search_volume_score=volume_score, 

103 competition_score=competition_score, 

104 value_score=value_score, 

105 overall_score=overall_score, 

106 recommendation=recommendation, 

107 )