v1.1.0: 北向资金/5日趋势/关键词增强/本地快照
Browse files- scripts/analyzer.py +186 -504
scripts/analyzer.py
CHANGED
|
@@ -1,504 +1,186 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
#
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
"""获取热门板块"""
|
| 188 |
-
try:
|
| 189 |
-
import akshare as ak
|
| 190 |
-
import warnings
|
| 191 |
-
warnings.filterwarnings("ignore")
|
| 192 |
-
|
| 193 |
-
df = ak.stock_board_industry_name_em()
|
| 194 |
-
if df is not None and not df.empty:
|
| 195 |
-
sectors = []
|
| 196 |
-
for _, row in df.head(15).iterrows():
|
| 197 |
-
sectors.append({
|
| 198 |
-
"name": str(row.get("板块名称", "")),
|
| 199 |
-
"change_pct": float(row.get("涨跌幅", 0)),
|
| 200 |
-
"leader": str(row.get("领涨股票", "")),
|
| 201 |
-
"leader_change": float(row.get("领涨股票-涨跌幅", 0)) if "领涨股票-涨跌幅" in row else 0,
|
| 202 |
-
"up_count": int(row.get("上涨家数", 0)) if "上涨家数" in row else 0,
|
| 203 |
-
"down_count": int(row.get("下跌家数", 0)) if "下跌家数" in row else 0,
|
| 204 |
-
})
|
| 205 |
-
return sectors
|
| 206 |
-
return []
|
| 207 |
-
except Exception as e:
|
| 208 |
-
log(f"⚠️ 板块数据获取失败: {e}")
|
| 209 |
-
return []
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
def fetch_top_stocks():
|
| 213 |
-
"""获取涨幅/跌幅前10"""
|
| 214 |
-
try:
|
| 215 |
-
import akshare as ak
|
| 216 |
-
import warnings
|
| 217 |
-
warnings.filterwarnings("ignore")
|
| 218 |
-
|
| 219 |
-
df = ak.stock_zh_a_spot_em()
|
| 220 |
-
if df is not None and not df.empty:
|
| 221 |
-
# 涨幅前10
|
| 222 |
-
top_up = df.nlargest(10, "涨跌幅")[["代码", "名称", "涨跌幅", "最新价", "成交额"]].to_dict("records")
|
| 223 |
-
# 跌幅前10
|
| 224 |
-
top_down = df.nsmallest(10, "涨跌幅")[["代码", "名称", "涨跌幅", "最新价", "成交额"]].to_dict("records")
|
| 225 |
-
# 成交额前10
|
| 226 |
-
top_volume = df.nlargest(10, "成交额")[["代码", "名称", "涨跌幅", "最新价", "成交额"]].to_dict("records")
|
| 227 |
-
|
| 228 |
-
return {
|
| 229 |
-
"涨幅榜": [{"code": str(r["代码"]), "name": str(r["名称"]), "change_pct": float(r["涨跌幅"]), "price": float(r["最新价"]) if r["最新价"] else 0, "volume": float(r["成交额"]) if r["成交额"] else 0} for r in top_up],
|
| 230 |
-
"跌幅榜": [{"code": str(r["代码"]), "name": str(r["名称"]), "change_pct": float(r["涨跌幅"]), "price": float(r["最新价"]) if r["最新价"] else 0, "volume": float(r["成交额"]) if r["成交额"] else 0} for r in top_down],
|
| 231 |
-
"成交榜": [{"code": str(r["代码"]), "name": str(r["名称"]), "change_pct": float(r["涨跌幅"]), "price": float(r["最新价"]) if r["最新价"] else 0, "volume": float(r["成交额"]) if r["成交额"] else 0} for r in top_volume],
|
| 232 |
-
}
|
| 233 |
-
return {}
|
| 234 |
-
except Exception as e:
|
| 235 |
-
log(f"⚠️ 个股排行获取失败: {e}")
|
| 236 |
-
return {}
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
# ============================================================
|
| 240 |
-
# 3. 关联分析
|
| 241 |
-
# ============================================================
|
| 242 |
-
def analyze_correlation(stock_hot, zt_dt, sectors):
|
| 243 |
-
"""分析热搜与行情的关联"""
|
| 244 |
-
analysis = {
|
| 245 |
-
"hot_stock_mentions": [],
|
| 246 |
-
"hot_and_zt": [],
|
| 247 |
-
"hot_sectors": [],
|
| 248 |
-
"insights": [],
|
| 249 |
-
}
|
| 250 |
-
|
| 251 |
-
# 提取热搜中的个股名
|
| 252 |
-
stock_names = []
|
| 253 |
-
for item in stock_hot:
|
| 254 |
-
keyword = item["keyword"]
|
| 255 |
-
# 去掉 # 号和通用词
|
| 256 |
-
clean = keyword.replace("#", "")
|
| 257 |
-
if 2 <= len(clean) <= 8:
|
| 258 |
-
stock_names.append(clean)
|
| 259 |
-
|
| 260 |
-
analysis["hot_stock_mentions"] = stock_names[:10]
|
| 261 |
-
|
| 262 |
-
# 与涨停板交叉
|
| 263 |
-
zt_names = [item["name"] for item in zt_dt.get("涨停", [])]
|
| 264 |
-
zt_reasons = {item["name"]: item.get("reason", "") for item in zt_dt.get("涨停", [])}
|
| 265 |
-
mentioned_and_zt = [name for name in stock_names if name in zt_names]
|
| 266 |
-
|
| 267 |
-
if mentioned_and_zt:
|
| 268 |
-
analysis["hot_and_zt"] = mentioned_and_zt
|
| 269 |
-
analysis["insights"].append(
|
| 270 |
-
f"🔥 同时出现在微博热搜和涨停板: {', '.join(mentioned_and_zt)}"
|
| 271 |
-
)
|
| 272 |
-
|
| 273 |
-
# 热搜板块
|
| 274 |
-
sector_keywords = []
|
| 275 |
-
for item in stock_hot:
|
| 276 |
-
kw = item["keyword"]
|
| 277 |
-
if any(w in kw for w in ["板块", "概念", "题材"]):
|
| 278 |
-
sector_keywords.append(kw)
|
| 279 |
-
|
| 280 |
-
if sector_keywords:
|
| 281 |
-
analysis["hot_sectors"] = sector_keywords
|
| 282 |
-
analysis["insights"].append(
|
| 283 |
-
f"📊 热搜板块关键词: {', '.join(sector_keywords[:5])}"
|
| 284 |
-
)
|
| 285 |
-
|
| 286 |
-
# 涨停原因分析
|
| 287 |
-
if zt_dt.get("涨停"):
|
| 288 |
-
reasons = {}
|
| 289 |
-
for item in zt_dt["涨停"]:
|
| 290 |
-
reason = item.get("reason", "").strip()
|
| 291 |
-
if reason:
|
| 292 |
-
reasons[reason] = reasons.get(reason, 0) + 1
|
| 293 |
-
if reasons:
|
| 294 |
-
top_reasons = sorted(reasons.items(), key=lambda x: -x[1])[:3]
|
| 295 |
-
for reason, count in top_reasons:
|
| 296 |
-
analysis["insights"].append(f"📈 涨停原因「{reason}」: {count} 只")
|
| 297 |
-
|
| 298 |
-
return analysis
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
# ============================================================
|
| 302 |
-
# 4. 报告生成
|
| 303 |
-
# ============================================================
|
| 304 |
-
def format_hot(num):
|
| 305 |
-
"""格式化热度数字"""
|
| 306 |
-
if num >= 1000000:
|
| 307 |
-
return f"{num/10000:.0f}万"
|
| 308 |
-
elif num >= 10000:
|
| 309 |
-
return f"{num/10000:.1f}万"
|
| 310 |
-
return str(num)
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
def log(msg):
|
| 314 |
-
"""日志输出"""
|
| 315 |
-
if not JSON_MODE:
|
| 316 |
-
print(msg, file=sys.stderr)
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
def generate_report(data):
|
| 320 |
-
"""生成完整报告"""
|
| 321 |
-
now = datetime.now().strftime("%Y-%m-%d %H:%M")
|
| 322 |
-
|
| 323 |
-
lines = []
|
| 324 |
-
lines.append(f"📊 A股微博热搜分析报告")
|
| 325 |
-
lines.append(f"⏰ {now}")
|
| 326 |
-
lines.append("=" * 50)
|
| 327 |
-
|
| 328 |
-
# 大盘
|
| 329 |
-
market = data.get("market", [])
|
| 330 |
-
lines.append("")
|
| 331 |
-
lines.append("📈 【大盘概览】")
|
| 332 |
-
lines.append("-" * 40)
|
| 333 |
-
if market:
|
| 334 |
-
for m in market:
|
| 335 |
-
arrow = "🔴" if m["change_pct"] < 0 else "🟢"
|
| 336 |
-
lines.append(f" {arrow} {m['name']}: {m['close']} ({m['change_pct']:+.2f}%)")
|
| 337 |
-
else:
|
| 338 |
-
lines.append(" 数据获取中...")
|
| 339 |
-
|
| 340 |
-
# 微博热搜
|
| 341 |
-
stock_hot = data.get("stock_hot", [])
|
| 342 |
-
lines.append("")
|
| 343 |
-
lines.append(f"🔥 【微博A股热搜】 ({len(stock_hot)} 条)")
|
| 344 |
-
lines.append("-" * 40)
|
| 345 |
-
if stock_hot:
|
| 346 |
-
for item in stock_hot[:15]:
|
| 347 |
-
lines.append(f" #{item['keyword']}# 🔥{format_hot(item['hot'])} ({item['match_reason']})")
|
| 348 |
-
else:
|
| 349 |
-
lines.append(" 暂无A股相关热搜")
|
| 350 |
-
|
| 351 |
-
if BRIEF_MODE:
|
| 352 |
-
# 精简模式只显示涨停
|
| 353 |
-
lines.append("")
|
| 354 |
-
lines.append("🟢 【涨停板】")
|
| 355 |
-
lines.append("-" * 40)
|
| 356 |
-
zt = data.get("zt_dt", {}).get("涨停", [])
|
| 357 |
-
for item in zt[:10]:
|
| 358 |
-
lines.append(f" {item['name']}({item['code']}) +{item['change_pct']:.1f}% {item.get('reason', '')}")
|
| 359 |
-
|
| 360 |
-
lines.append("")
|
| 361 |
-
lines.append("=" * 50)
|
| 362 |
-
lines.append("📌 数据来源: 微博热搜 + AKShare")
|
| 363 |
-
return "\n".join(lines)
|
| 364 |
-
|
| 365 |
-
# 涨停
|
| 366 |
-
zt = data.get("zt_dt", {}).get("涨停", [])
|
| 367 |
-
lines.append("")
|
| 368 |
-
lines.append(f"🟢 【涨停板 TOP{min(15, len(zt))}】")
|
| 369 |
-
lines.append("-" * 40)
|
| 370 |
-
if zt:
|
| 371 |
-
for item in zt[:15]:
|
| 372 |
-
lines.append(f" {item['name']}({item['code']}) +{item['change_pct']:.1f}% {item.get('reason', '')}")
|
| 373 |
-
else:
|
| 374 |
-
lines.append(" 无涨停或数据获取中...")
|
| 375 |
-
|
| 376 |
-
# 跌停
|
| 377 |
-
dt = data.get("zt_dt", {}).get("跌停", [])
|
| 378 |
-
lines.append("")
|
| 379 |
-
lines.append(f"🔴 【跌停板 TOP{min(15, len(dt))}】")
|
| 380 |
-
lines.append("-" * 40)
|
| 381 |
-
if dt:
|
| 382 |
-
for item in dt[:15]:
|
| 383 |
-
lines.append(f" {item['name']}({item['code']}) {item['change_pct']:.1f}%")
|
| 384 |
-
else:
|
| 385 |
-
lines.append(" 无跌停或数据获取中...")
|
| 386 |
-
|
| 387 |
-
# 热门板块
|
| 388 |
-
sectors = data.get("sectors", [])
|
| 389 |
-
lines.append("")
|
| 390 |
-
lines.append(f"📊 【热门板块 TOP{min(10, len(sectors))}】")
|
| 391 |
-
lines.append("-" * 40)
|
| 392 |
-
if sectors:
|
| 393 |
-
for item in sectors[:10]:
|
| 394 |
-
arrow = "🔴" if item["change_pct"] < 0 else "🟢"
|
| 395 |
-
lines.append(f" {arrow} {item['name']}: {item['change_pct']:+.2f}% 领涨: {item['leader']}")
|
| 396 |
-
else:
|
| 397 |
-
lines.append(" 数据获取中...")
|
| 398 |
-
|
| 399 |
-
# 个股排行
|
| 400 |
-
stocks = data.get("stocks", {})
|
| 401 |
-
if stocks.get("涨幅榜"):
|
| 402 |
-
lines.append("")
|
| 403 |
-
lines.append("📈 【今日涨幅榜 TOP5】")
|
| 404 |
-
lines.append("-" * 40)
|
| 405 |
-
for item in stocks["涨幅榜"][:5]:
|
| 406 |
-
lines.append(f" 🟢 {item['name']}({item['code']}) +{item['change_pct']:.1f}% ¥{item['price']}")
|
| 407 |
-
|
| 408 |
-
if stocks.get("成交榜"):
|
| 409 |
-
lines.append("")
|
| 410 |
-
lines.append("💰 【今日成交额 TOP5】")
|
| 411 |
-
lines.append("-" * 40)
|
| 412 |
-
for item in stocks["成交榜"][:5]:
|
| 413 |
-
vol_str = f"{item['volume']/100000000:.1f}亿" if item['volume'] >= 100000000 else f"{item['volume']/10000:.0f}万"
|
| 414 |
-
lines.append(f" 💰 {item['name']}({item['code']}) {vol_str} {item['change_pct']:+.1f}%")
|
| 415 |
-
|
| 416 |
-
# 关联分析
|
| 417 |
-
corr = data.get("correlation", {})
|
| 418 |
-
lines.append("")
|
| 419 |
-
lines.append("🔗 【热搜 vs 行情 关联分析】")
|
| 420 |
-
lines.append("-" * 40)
|
| 421 |
-
|
| 422 |
-
if corr.get("hot_stock_mentions"):
|
| 423 |
-
lines.append(f" 💬 热搜提及个股: {', '.join(corr['hot_stock_mentions'][:5])}")
|
| 424 |
-
|
| 425 |
-
if corr.get("hot_and_zt"):
|
| 426 |
-
lines.append(f" 🔥 热搜+涨停双重热度: {', '.join(corr['hot_and_zt'])}")
|
| 427 |
-
|
| 428 |
-
if corr.get("hot_sectors"):
|
| 429 |
-
lines.append(f" 📊 热搜板块: {', '.join(corr['hot_sectors'][:3])}")
|
| 430 |
-
|
| 431 |
-
if corr.get("insights"):
|
| 432 |
-
for note in corr["insights"]:
|
| 433 |
-
lines.append(f" {note}")
|
| 434 |
-
|
| 435 |
-
if not corr.get("insights") and not corr.get("hot_stock_mentions"):
|
| 436 |
-
lines.append(" 暂无明显关联")
|
| 437 |
-
|
| 438 |
-
lines.append("")
|
| 439 |
-
lines.append("=" * 50)
|
| 440 |
-
lines.append("📌 数据来源: 微博热搜 + AKShare (东方财富)")
|
| 441 |
-
lines.append("⚠️ 仅供参考,不构成投资建议")
|
| 442 |
-
|
| 443 |
-
return "\n".join(lines)
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
# ============================================================
|
| 447 |
-
# Main
|
| 448 |
-
# ============================================================
|
| 449 |
-
def main():
|
| 450 |
-
log("🔍 正在抓取数据...\n")
|
| 451 |
-
|
| 452 |
-
data = {}
|
| 453 |
-
|
| 454 |
-
# 1. 微博热搜
|
| 455 |
-
if not NO_WEIBO:
|
| 456 |
-
log(" 📱 微博热搜...")
|
| 457 |
-
hot_list = fetch_weibo_hot()
|
| 458 |
-
data["weibo_hot_total"] = len(hot_list)
|
| 459 |
-
data["stock_hot"] = filter_stock_keywords(hot_list)
|
| 460 |
-
else:
|
| 461 |
-
data["stock_hot"] = []
|
| 462 |
-
|
| 463 |
-
# 2. 大盘指数
|
| 464 |
-
if not NO_MARKET:
|
| 465 |
-
log(" 📈 大盘指数...")
|
| 466 |
-
data["market"] = fetch_market_overview()
|
| 467 |
-
else:
|
| 468 |
-
data["market"] = []
|
| 469 |
-
|
| 470 |
-
# 3. 涨停/跌停
|
| 471 |
-
if not NO_MARKET:
|
| 472 |
-
log(" 🟢 涨停/跌停...")
|
| 473 |
-
data["zt_dt"] = fetch_zt_dt()
|
| 474 |
-
else:
|
| 475 |
-
data["zt_dt"] = {"涨停": [], "跌停": []}
|
| 476 |
-
|
| 477 |
-
# 4. 热门板块
|
| 478 |
-
if not NO_MARKET and not BRIEF_MODE:
|
| 479 |
-
log(" 📊 热门板块...")
|
| 480 |
-
data["sectors"] = fetch_hot_sectors()
|
| 481 |
-
else:
|
| 482 |
-
data["sectors"] = []
|
| 483 |
-
|
| 484 |
-
# 5. 个股排行
|
| 485 |
-
if not NO_MARKET and not BRIEF_MODE:
|
| 486 |
-
log(" 📈 个股排行...")
|
| 487 |
-
data["stocks"] = fetch_top_stocks()
|
| 488 |
-
else:
|
| 489 |
-
data["stocks"] = {}
|
| 490 |
-
|
| 491 |
-
# 6. 关联分析
|
| 492 |
-
log(" 🔗 关联分析...")
|
| 493 |
-
data["correlation"] = analyze_correlation(data["stock_hot"], data["zt_dt"], data["sectors"])
|
| 494 |
-
|
| 495 |
-
# 7. 输出
|
| 496 |
-
if JSON_MODE:
|
| 497 |
-
data["timestamp"] = datetime.now().isoformat()
|
| 498 |
-
print(json.dumps(data, ensure_ascii=False, indent=2))
|
| 499 |
-
else:
|
| 500 |
-
print(generate_report(data))
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
if __name__ == "__main__":
|
| 504 |
-
main()
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: CNY RMB A股 China A shares Stock
|
| 3 |
+
version: 1.1.0
|
| 4 |
+
description: >
|
| 5 |
+
CNY RMB A股热搜分析 - China A Shares Stock Skill
|
| 6 |
+
微博热搜 + A股行情 + 关联分析,一站式掌握市场热点。
|
| 7 |
+
关键词:A股, 大A, A-shares, China A, Onshore, 涨停, 跌停, 热搜
|
| 8 |
+
applyTo: "**"
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# CNY RMB A股热搜分析
|
| 12 |
+
# China A Shares Stock Skill
|
| 13 |
+
|
| 14 |
+
微博热搜 + A股行情 + 关联分析,一站式掌握市场热点。
|
| 15 |
+
|
| 16 |
+
> **关于作者** — 米粉,A股老韭菜,美股老韭菜,期货老韭菜,币圈老韭菜,被割多了,现在只看不玩,用MIMO做个Skill大家娱乐围观A股行情,好用记得回来点星星。⭐
|
| 17 |
+
>
|
| 18 |
+
> Mi Fan 🍚 | Rekt veteran: A-shares, US stocks, futures, crypto 📉 | Now just watching 👀 | Built with MIMO for fun | Star if you like it ⭐
|
| 19 |
+
>
|
| 20 |
+
> **功能清单:**
|
| 21 |
+
> - ✅ 微博实时热搜抓取 + A股关键词筛选(v1.1 增强)
|
| 22 |
+
> - ✅ 大盘指数(上证/深证/创业板)
|
| 23 |
+
> - ✅ 涨停板 / 跌停板 TOP 列表
|
| 24 |
+
> - ✅ 热门板块排行
|
| 25 |
+
> - ✅ 热搜 vs 行情关联分析
|
| 26 |
+
> - ✅ 🆕 北向资金实时数据(沪股通/深股通)
|
| 27 |
+
> - ✅ 🆕 大盘5日趋势 + 迷你趋势图
|
| 28 |
+
> - ✅ 🆕 行业/板块关键词库增强(50+板块)
|
| 29 |
+
> - ✅ 🆕 本地快照缓存 + 历史数据对比
|
| 30 |
+
> - ✅ `--json` 结构化输出
|
| 31 |
+
> - ✅ `--brief` 精简模式(仅热搜 + 涨停)
|
| 32 |
+
> - ✅ `--trend` 趋势模式(含大盘5日走势)
|
| 33 |
+
|
| 34 |
+
## When to Use
|
| 35 |
+
|
| 36 |
+
| Situation | Use this skill? |
|
| 37 |
+
|---|---|
|
| 38 |
+
| 用户说"A股分析" / "股市热搜" / "今天行情" | ✅ Yes |
|
| 39 |
+
| 用户问"今天有什么热门股票" | ✅ Yes |
|
| 40 |
+
| 用户想看微博上大家在讨论什么股票 | ✅ Yes |
|
| 41 |
+
| 盘后复盘 / 盘中监控 | ✅ Yes |
|
| 42 |
+
| 用户问"北向资金今天流入多少" | ✅ Yes |
|
| 43 |
+
| 用户问"大盘最近走势怎么样" | ✅ Yes |
|
| 44 |
+
|
| 45 |
+
## Usage
|
| 46 |
+
|
| 47 |
+
```bash
|
| 48 |
+
python3 "{baseDir}/scripts/analyzer.py" [options]
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
### Options
|
| 52 |
+
|
| 53 |
+
| Flag | Description |
|
| 54 |
+
|------|-------------|
|
| 55 |
+
| `--json` | JSON 格式输出 |
|
| 56 |
+
| `--brief` | 精简模式:仅热搜 + 涨停 |
|
| 57 |
+
| `--trend` | 趋势模式:含大盘5日走势 |
|
| 58 |
+
| `--no-weibo` | 跳过微博数据(只看行情) |
|
| 59 |
+
| `--no-market` | 跳过行情数据(只看热搜) |
|
| 60 |
+
|
| 61 |
+
### Examples
|
| 62 |
+
|
| 63 |
+
```bash
|
| 64 |
+
# 完整分析
|
| 65 |
+
python3 "{baseDir}/scripts/analyzer.py"
|
| 66 |
+
|
| 67 |
+
# 精简模式
|
| 68 |
+
python3 "{baseDir}/scripts/analyzer.py" --brief
|
| 69 |
+
|
| 70 |
+
# 趋势模式(含大盘5日走势)
|
| 71 |
+
python3 "{baseDir}/scripts/analyzer.py" --trend
|
| 72 |
+
|
| 73 |
+
# JSON 输出
|
| 74 |
+
python3 "{baseDir}/scripts/analyzer.py" --json
|
| 75 |
+
|
| 76 |
+
# 只看行情
|
| 77 |
+
python3 "{baseDir}/scripts/analyzer.py" --no-weibo
|
| 78 |
+
|
| 79 |
+
# 只看热搜
|
| 80 |
+
python3 "{baseDir}/scripts/analyzer.py" --no-market
|
| 81 |
+
|
| 82 |
+
# 趋势 + 精简
|
| 83 |
+
python3 "{baseDir}/scripts/analyzer.py" --trend --brief
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
## v1.1 新增内容
|
| 87 |
+
|
| 88 |
+
### 🌊 北向资金
|
| 89 |
+
- 沪股通/深股通净买入数据
|
| 90 |
+
- 实时净流入/流出金额
|
| 91 |
+
- 自动格式化为亿/万亿
|
| 92 |
+
|
| 93 |
+
### 📉 大盘5日趋势
|
| 94 |
+
- `--trend` 开启趋势模式
|
| 95 |
+
- 迷你趋势图可视化
|
| 96 |
+
- 5日累计涨跌幅
|
| 97 |
+
|
| 98 |
+
### 🔍 关键词匹配增强
|
| 99 |
+
- 新增 50+ 行业/板块关键词
|
| 100 |
+
- 覆盖科技、新能源、消费、金融、制造等领域
|
| 101 |
+
- 板块级别精确匹配,减少模糊匹配
|
| 102 |
+
|
| 103 |
+
### 📅 本地快照
|
| 104 |
+
- 自动保存每日数据到 `.cache/`
|
| 105 |
+
- 报告底部显示最近5天数据对比
|
| 106 |
+
- 涨停/跌停家数变化一目了然
|
| 107 |
+
|
| 108 |
+
## 输出格式
|
| 109 |
+
|
| 110 |
+
```
|
| 111 |
+
📊 A股微博热搜分析报告 v1.1
|
| 112 |
+
⏰ 2026-05-01 09:30
|
| 113 |
+
==================================================
|
| 114 |
+
|
| 115 |
+
📈 【大盘概览】
|
| 116 |
+
----------------------------------------
|
| 117 |
+
🟢 上证指数: 3288.41 (+0.52%)
|
| 118 |
+
🔴 深证成指: 10245.67 (-0.09%)
|
| 119 |
+
🔴 创业板指: 2045.12 (-0.27%)
|
| 120 |
+
|
| 121 |
+
🌊 【北向资金】
|
| 122 |
+
----------------------------------------
|
| 123 |
+
🟢 净流入: 45.23亿
|
| 124 |
+
沪股通净买入: 28.10亿
|
| 125 |
+
深股通净买入: 17.13亿
|
| 126 |
+
|
| 127 |
+
📉 【近5日趋势】
|
| 128 |
+
----------------------------------------
|
| 129 |
+
📈 上证指数: +2.15% (5日)
|
| 130 |
+
▓▓▓▓▓▓░░ ▓▓▓▓▓░░░ ▓▓▓▓▓▓░░ ▓▓▓▓▓▓▓░ ▓▓▓▓▓▓▓░
|
| 131 |
+
3250.12 → 3265.44 → 3278.90 → 3285.33 → 3288.41
|
| 132 |
+
|
| 133 |
+
🔥 【微博A股热搜】
|
| 134 |
+
----------------------------------------
|
| 135 |
+
#寒武纪涨停# 🔥17.5万 (板块「AI」)
|
| 136 |
+
#A股牛市来了# 🔥12.3万 (包含「A股」「牛市」)
|
| 137 |
+
|
| 138 |
+
🟢 【涨停板 TOP10】
|
| 139 |
+
----------------------------------------
|
| 140 |
+
寒武纪(688256) +20.0% AI芯片
|
| 141 |
+
...
|
| 142 |
+
|
| 143 |
+
🔗 【热搜 vs 行情 关联分析】
|
| 144 |
+
----------------------------------------
|
| 145 |
+
💬 热搜提及个股: 寒武纪, 中科曙光
|
| 146 |
+
🔥 热搜+涨停双重热度: 寒武纪
|
| 147 |
+
📊 涨停原因「AI芯片」: 3 只
|
| 148 |
+
|
| 149 |
+
📅 【历史数据对比】
|
| 150 |
+
----------------------------------------
|
| 151 |
+
📌 2026-05-01: 涨停42家 / 跌停5家 / 板块15个 北向: 45.23亿
|
| 152 |
+
📌 2026-04-30: 涨停38家 / 跌停8家 / 板块14个 北向: -12.50亿
|
| 153 |
+
📌 2026-04-29: 涨停45家 / 跌停3家 / 板块15个 北向: 32.80亿
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
+
## 数据源
|
| 157 |
+
|
| 158 |
+
| 源 | 说明 | 需要 API Key |
|
| 159 |
+
|----|------|-------------|
|
| 160 |
+
| 微博热搜 | 公开 API | ❌ 不需要 |
|
| 161 |
+
| AKShare (东方财富) | A股行情 + 北向资金 | ❌ 不需要 |
|
| 162 |
+
|
| 163 |
+
## 依赖
|
| 164 |
+
|
| 165 |
+
- Python 3.8+
|
| 166 |
+
- akshare (`pip3 install akshare`)
|
| 167 |
+
|
| 168 |
+
## 版本历史
|
| 169 |
+
|
| 170 |
+
### v1.1.0 (2026-05-01)
|
| 171 |
+
|
| 172 |
+
- 🌊 新增北向资金数据(沪股通/深股通净买入)
|
| 173 |
+
- 📉 新增 `--trend` 大盘5日趋势 + 迷你趋势图
|
| 174 |
+
- 🔍 关键词匹配增强:50+行业/板块关键词库
|
| 175 |
+
- 📅 本地快照缓存 + 历史数据对比
|
| 176 |
+
- 🔧 修复关键词模糊匹配过于宽泛的问题
|
| 177 |
+
- 📝 报告标题标注版本号
|
| 178 |
+
|
| 179 |
+
### v1.0.0 (2026-05-01)
|
| 180 |
+
|
| 181 |
+
- 🚀 首发:微博热搜抓取 + A股行情 + 关联分析
|
| 182 |
+
- 📈 大盘指数:上证/深证/创业板
|
| 183 |
+
- 🟢 涨停板/跌停板 TOP 列表
|
| 184 |
+
- 📊 热门板块排行
|
| 185 |
+
- 🔗 热搜 vs 行情关联分析
|
| 186 |
+
- 📱 支持 `--json` / `--brief` / `--no-weibo` / `--no-market`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|