فهرست منبع

修改微信指数判断

xueyiming 13 ساعت پیش
والد
کامیت
ba9f051409
6فایلهای تغییر یافته به همراه52 افزوده شده و 20 حذف شده
  1. 8 8
      app/core/config.py
  2. 7 6
      app/hot_content/config.py
  3. 2 2
      app/hot_content/types.py
  4. 2 0
      app/hot_content/wxindex_heat_pattern.py
  5. 29 0
      app/hot_content/wxindex_trend.py
  6. 4 4
      app/scheduler.py

+ 8 - 8
app/core/config.py

@@ -161,9 +161,9 @@ class Settings:
     wxindex_llm_max_tokens: int = 4000
     wxindex_api_url: str = "http://crawapi.piaoquantv.com/crawler/wei_xin/wxindex"
     wxindex_lookback_days: int = 7
-    wxindex_words_cron_hour: int = 10
+    wxindex_words_cron_hours: str = "10,14"
     wxindex_words_cron_minute: int = 0
-    wxindex_heat_pattern_cron_hour: int = 11
+    wxindex_heat_pattern_cron_hours: str = "11,15"
     wxindex_heat_pattern_cron_minute: int = 0
     demand_event_sense_threshold: float = 6.0
     demand_senior_fit_threshold: float = 6.0
@@ -347,17 +347,17 @@ class Settings:
                 "WXINDEX_LOOKBACK_DAYS",
                 defaults.wxindex_lookback_days,
             ),
-            wxindex_words_cron_hour=_env_int(
-                "WXINDEX_WORDS_CRON_HOUR",
-                defaults.wxindex_words_cron_hour,
+            wxindex_words_cron_hours=_env(
+                "WXINDEX_WORDS_CRON_HOURS",
+                defaults.wxindex_words_cron_hours,
             ),
             wxindex_words_cron_minute=_env_int(
                 "WXINDEX_WORDS_CRON_MINUTE",
                 defaults.wxindex_words_cron_minute,
             ),
-            wxindex_heat_pattern_cron_hour=_env_int(
-                "WXINDEX_HEAT_PATTERN_CRON_HOUR",
-                defaults.wxindex_heat_pattern_cron_hour,
+            wxindex_heat_pattern_cron_hours=_env(
+                "WXINDEX_HEAT_PATTERN_CRON_HOURS",
+                defaults.wxindex_heat_pattern_cron_hours,
             ),
             wxindex_heat_pattern_cron_minute=_env_int(
                 "WXINDEX_HEAT_PATTERN_CRON_MINUTE",

+ 7 - 6
app/hot_content/config.py

@@ -264,17 +264,18 @@ def load_flow_config(interval_override: int | None = None) -> FlowConfig:
             "WXINDEX_LOOKBACK_DAYS",
             settings.wxindex_lookback_days,
         ),
-        wxindex_words_cron_hour=_get_env_int(
-            "WXINDEX_WORDS_CRON_HOUR",
-            settings.wxindex_words_cron_hour,
+        wxindex_words_cron_hours=_parse_cron_hours(
+            _get_env("WXINDEX_WORDS_CRON_HOURS", settings.wxindex_words_cron_hours)
         ),
         wxindex_words_cron_minute=_get_env_int(
             "WXINDEX_WORDS_CRON_MINUTE",
             settings.wxindex_words_cron_minute,
         ),
-        wxindex_heat_pattern_cron_hour=_get_env_int(
-            "WXINDEX_HEAT_PATTERN_CRON_HOUR",
-            settings.wxindex_heat_pattern_cron_hour,
+        wxindex_heat_pattern_cron_hours=_parse_cron_hours(
+            _get_env(
+                "WXINDEX_HEAT_PATTERN_CRON_HOURS",
+                settings.wxindex_heat_pattern_cron_hours,
+            )
         ),
         wxindex_heat_pattern_cron_minute=_get_env_int(
             "WXINDEX_HEAT_PATTERN_CRON_MINUTE",

+ 2 - 2
app/hot_content/types.py

@@ -56,9 +56,9 @@ class FlowConfig:
     wxindex_llm_max_tokens: int
     wxindex_api_url: str
     wxindex_lookback_days: int
-    wxindex_words_cron_hour: int
+    wxindex_words_cron_hours: str
     wxindex_words_cron_minute: int
-    wxindex_heat_pattern_cron_hour: int
+    wxindex_heat_pattern_cron_hours: str
     wxindex_heat_pattern_cron_minute: int
     demand_event_sense_threshold: float
     demand_senior_fit_threshold: float

+ 2 - 0
app/hot_content/wxindex_heat_pattern.py

@@ -25,6 +25,7 @@ from app.hot_content.types import FlowConfig
 from app.hot_content.wxindex_trend import (
     HEAT_RISING_ADJACENT_UP_RATIO,
     HEAT_RISING_OVERALL_CHANGE_RATE,
+    HEAT_RISING_RECENT_DROP_RATE,
     HEAT_RISING_WINDOW_CHANGE_RATE,
     HEAT_SPIKE_BASELINE_FLOOR,
     HEAT_SPIKE_RATIO,
@@ -43,6 +44,7 @@ WXINDEX_SPIKE_BASELINE_FLOOR = HEAT_SPIKE_BASELINE_FLOOR
 WXINDEX_RISING_OVERALL_CHANGE_RATE = HEAT_RISING_OVERALL_CHANGE_RATE
 WXINDEX_RISING_WINDOW_CHANGE_RATE = HEAT_RISING_WINDOW_CHANGE_RATE
 WXINDEX_RISING_ADJACENT_UP_RATIO = HEAT_RISING_ADJACENT_UP_RATIO
+WXINDEX_RISING_RECENT_DROP_RATE = HEAT_RISING_RECENT_DROP_RATE
 WXINDEX_WORD_SENIOR_FIT_NORMALIZED_THRESHOLD = 0.6
 WXINDEX_WORD_LLM_BATCH_SIZE = 10
 

+ 29 - 0
app/hot_content/wxindex_trend.py

@@ -15,6 +15,7 @@ DOWN_WINDOW_CHANGE_RATE = -0.02
 HEAT_RISING_OVERALL_CHANGE_RATE = 0.15
 HEAT_RISING_WINDOW_CHANGE_RATE = 0.12
 HEAT_RISING_ADJACENT_UP_RATIO = 0.65
+HEAT_RISING_RECENT_DROP_RATE = -0.15
 HEAT_SPIKE_BASELINE_FLOOR = 50_000.0
 HEAT_SPIKE_RATIO = 2.5
 
@@ -96,6 +97,27 @@ def is_wxindex_rising_scores(
     )
 
 
+def _has_significant_recent_drop(
+    scores: list[float],
+    *,
+    drop_rate_threshold: float = HEAT_RISING_RECENT_DROP_RATE,
+) -> bool:
+    """最近一天热度相较昨天或前天是否出现大幅度下降。"""
+    if len(scores) < 2:
+        return False
+
+    latest = scores[-1]
+    prior_scores = [scores[-2]]
+    if len(scores) >= 3:
+        prior_scores.append(scores[-3])
+
+    for prior in prior_scores:
+        change_rate = (latest - prior) / max(prior, 1.0)
+        if change_rate <= drop_rate_threshold:
+            return True
+    return False
+
+
 def is_wxindex_heat_rising_scores(
     scores: list[float],
     *,
@@ -103,6 +125,7 @@ def is_wxindex_heat_rising_scores(
     overall_change_rate: float = HEAT_RISING_OVERALL_CHANGE_RATE,
     window_change_rate_threshold: float = HEAT_RISING_WINDOW_CHANGE_RATE,
     adjacent_up_ratio: float = HEAT_RISING_ADJACENT_UP_RATIO,
+    recent_drop_rate_threshold: float = HEAT_RISING_RECENT_DROP_RATE,
 ) -> bool:
     """热度模式任务:判断区间内是否持续上涨。"""
     if len(scores) < min_points:
@@ -123,6 +146,12 @@ def is_wxindex_heat_rising_scores(
     if last_score <= first_score:
         return False
 
+    if _has_significant_recent_drop(
+        scores,
+        drop_rate_threshold=recent_drop_rate_threshold,
+    ):
+        return False
+
     adjacent_total = len(scores) - 1
     if adjacent_total <= 0:
         return False

+ 4 - 4
app/scheduler.py

@@ -151,7 +151,7 @@ def register_wxindex_words_refresh_job(scheduler: Any, config: FlowConfig) -> No
     scheduler.add_job(
         run_wxindex_words_refresh_job,
         trigger="cron",
-        hour=config.wxindex_words_cron_hour,
+        hour=config.wxindex_words_cron_hours,
         minute=config.wxindex_words_cron_minute,
         timezone=SHANGHAI_TZ,
         args=[config],
@@ -167,7 +167,7 @@ def register_wxindex_heat_pattern_job(scheduler: Any, config: FlowConfig) -> Non
     scheduler.add_job(
         run_wxindex_heat_pattern_job,
         trigger="cron",
-        hour=config.wxindex_heat_pattern_cron_hour,
+        hour=config.wxindex_heat_pattern_cron_hours,
         minute=config.wxindex_heat_pattern_cron_minute,
         timezone=SHANGHAI_TZ,
         args=[config],
@@ -193,9 +193,9 @@ def start_scheduler() -> None:
         "'wxindex_heat_pattern'], "
         f"hot_cron={config.hot_flow_cron_hours}:{config.hot_flow_cron_minute:02d}, "
         f"decode_result_interval={config.decode_result_interval_seconds}s, "
-        f"wxindex_words_cron={config.wxindex_words_cron_hour}:{config.wxindex_words_cron_minute:02d}, "
+        f"wxindex_words_cron={config.wxindex_words_cron_hours}:{config.wxindex_words_cron_minute:02d}, "
         f"wxindex_heat_pattern_cron="
-        f"{config.wxindex_heat_pattern_cron_hour}:{config.wxindex_heat_pattern_cron_minute:02d}"
+        f"{config.wxindex_heat_pattern_cron_hours}:{config.wxindex_heat_pattern_cron_minute:02d}"
     )
     scheduler.start()