"""东方财富 CHOICE API 公司介绍 + 所属行业抓取工具。 - 输入: 股票代码列表 (如 ['603233.SH']) - 输出: pandas DataFrame (公司基本资料 / 所属行业) - 不需要登录, 不需要 cookie, 无文件落盘 """ from __future__ import annotations import pandas as pd from utils._emchoice import fetch_report def _fetch_one(secucode: str, params: dict[str, str]) -> pd.DataFrame: """按给定参数拉一只股票的数据.""" rows = fetch_report(params) df = pd.DataFrame(rows) if not df.empty: df["SECUCODE"] = secucode return df def _concat(frames: list[pd.DataFrame]) -> pd.DataFrame: if not frames: return pd.DataFrame() return pd.concat(frames, ignore_index=True) # ---------------------------------------------------------------- 公司介绍 def _build_company_params(secucode: str) -> dict[str, str]: """构造 RPT_HSF9_BASIC_ORGINFO 查询参数 (公司基本资料).""" return { "source": "CHOICE", "reportName": "RPT_HSF9_BASIC_ORGINFO", "columns": "HSF9_ORGINFO", "quoteColumns": "", "filter": f'(SECUCODE="{secucode}")', "pageNumber": "1", "pageSize": "200", "client": "SW", } def get_company_info(secucodes: list[str]) -> pd.DataFrame: """抓取指定股票的公司介绍 (基本资料, 每只 1 行).""" codes = [code.strip() for code in secucodes if code.strip()] if not codes: return pd.DataFrame() frames = [_fetch_one(code, _build_company_params(code)) for code in codes] return _concat([df for df in frames if not df.empty]) # ---------------------------------------------------------------- 所属行业 def _build_industry_params(secucode: str) -> dict[str, str]: """构造 RPT_STOCKF9_INDUSTRY 查询参数 (当前生效的行业分类).""" return { "reportName": "RPT_STOCKF9_INDUSTRY", "columns": ( "SECUCODE,SECURITY_CODE,SECURITY_NAME_ABBR,INDUSTRY_TYPE_CODE," "INDUSTRY_TYPE,INDUSTRY_NAME,INDUSTRY_CODE,SECURITY_INNER_CODE," "INDUSTRY_NAME_MIN,INDUSTRY_CODE_MIN,ENTRY_DATE,OUT_DATE," "SECURITY_TYPE_CODE,STATE,STATE_CODE,RN" ), "quoteColumns": "", "filter": f'(SECUCODE="{secucode}")(STATE_CODE="1")', "pageNumber": "", "pageSize": "", "sortTypes": "1", "sortColumns": "RN", "source": "CHOICE", "client": "SW", } def get_industry(secucodes: list[str]) -> pd.DataFrame: """抓取指定股票的所属行业 (当前生效分类).""" codes = [code.strip() for code in secucodes if code.strip()] if not codes: return pd.DataFrame() frames = [_fetch_one(code, _build_industry_params(code)) for code in codes] return _concat([df for df in frames if not df.empty])