From ad5208c6cddc01203b24bffe6c32f04e7b946e2c Mon Sep 17 00:00:00 2001 From: hmo Date: Fri, 14 Aug 2026 21:43:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B8=AF=E8=82=A1=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=A1=A5=E9=87=871=E2=80=94=E2=80=94hk=5Fsector=5Fcollector?= =?UTF-8?q?=E8=A1=8C=E4=B8=9A=E5=BD=92=E5=B1=9E=E9=87=87=E9=9B=86(?= =?UTF-8?q?=E4=B8=9C=E8=B4=A2=E5=85=AC=E5=8F=B8=E6=A1=A3=E6=A1=88=E2=86=92?= =?UTF-8?q?stock=5Fsectors=E5=A4=8D=E7=94=A8=E8=A1=A8,source=3Dhk=5Fem)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/profile-scripts/hk_sector_collector.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 deploy/profile-scripts/hk_sector_collector.py diff --git a/deploy/profile-scripts/hk_sector_collector.py b/deploy/profile-scripts/hk_sector_collector.py new file mode 100644 index 00000000..6c6c64c1 --- /dev/null +++ b/deploy/profile-scripts/hk_sector_collector.py @@ -0,0 +1,73 @@ +#!/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 +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())