Files
MoFin/deploy/profile-scripts/hk_sector_collector.py
T

81 lines
2.7 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""hk_sector_collector.py — 港股通行业归属采集(阶段2数据补采)
数据源:akshare stock_hk_company_profile_em(东财港股公司档案,含"所属行业")。
写入:stock_sectors 表(code+sector_name 主键,source='hk_em',与A股同表复用)。
调度:一次性补采 + 之后随名单变动增量(周级)。
限速:0.4s/只(铁律),620只约5分钟。
"""
import sqlite3
import sys
import time
import warnings
# ── 消息通道统一路由(broadcast/xmpp by delivery) ──
try:
from messenger import install_stdio_hook as _msh
_msh()
except Exception:
pass
warnings.filterwarnings("ignore")
DB_PATH = "/home/hmo/MoFin/data/mofin.db"
SLEEP = 0.4
def fetch_industry(code):
"""东财港股公司档案 → 所属行业"""
import akshare as ak
try:
df = ak.stock_hk_company_profile_em(symbol=code)
if df is None or df.empty:
return None
row = df.iloc[0]
ind = row.get("所属行业")
return str(ind).strip() if ind and str(ind) != "nan" else None
except Exception:
return None
def main():
conn = sqlite3.connect(DB_PATH, timeout=30)
conn.execute("PRAGMA busy_timeout=30000")
codes = [r[0] for r in conn.execute(
"SELECT code FROM hk_connect_stocks WHERE is_active=1 ORDER BY code").fetchall()]
print(f"港股通行业归属采集:{len(codes)} 只", flush=True)
ok = empty = fail = 0
t0 = time.time()
for idx, code in enumerate(codes):
ind = fetch_industry(code)
if ind:
conn.execute(
"INSERT OR REPLACE INTO stock_sectors (code, sector_name, source, updated_at) "
"VALUES (?,?, 'hk_em', datetime('now','localtime'))",
(code, ind))
ok += 1
elif ind is None:
empty += 1
if (idx + 1) % 100 == 0:
conn.commit()
print(f" [{idx+1}/{len(codes)}] ok={ok} empty={empty} | {time.time()-t0:.0f}s", flush=True)
time.sleep(SLEEP)
conn.commit()
n = conn.execute("SELECT COUNT(*) FROM stock_sectors WHERE source='hk_em'").fetchone()[0]
top = conn.execute(
"SELECT sector_name, COUNT(*) c FROM stock_sectors WHERE source='hk_em' "
"GROUP BY sector_name ORDER BY c DESC LIMIT 10").fetchall()
conn.close()
print(f"\n完成:ok={ok} empty={empty} 耗时{time.time()-t0:.0f}s", flush=True)
print(f"stock_sectors 港股行业记录: {n} 条", flush=True)
print("行业分布 top10:", flush=True)
for name, c in top:
print(f" {name}: {c}", flush=True)
return 0
if __name__ == "__main__":
sys.exit(main())