优化数据获取
This commit is contained in:
+16
-212
@@ -617,14 +617,8 @@ class StockDataFetcher:
|
||||
except Exception as e:
|
||||
print(f"获取财务指标失败: {e}")
|
||||
|
||||
# 5. 获取季度业绩(使用问财)
|
||||
try:
|
||||
# 使用pywencai获取季报数据
|
||||
quarter_data = self._get_quarter_data_from_wencai(symbol)
|
||||
if quarter_data:
|
||||
financial_data["quarter_data"] = quarter_data
|
||||
except Exception as e:
|
||||
print(f"获取季度数据失败: {e}")
|
||||
# 注意:季报数据现在由 quarterly_report_data.py 模块使用 akshare 获取(8期完整季报)
|
||||
# 不再使用问财获取季报,避免重复
|
||||
|
||||
return financial_data
|
||||
|
||||
@@ -632,74 +626,10 @@ class StockDataFetcher:
|
||||
print(f"获取中国股票财务数据失败: {e}")
|
||||
return financial_data
|
||||
|
||||
def _get_quarter_data_from_wencai(self, symbol):
|
||||
"""使用问财获取季报数据 - 直接返回原始数据给AI分析"""
|
||||
try:
|
||||
# 构建查询语句 - 获取最近4个季度的数据
|
||||
query = f"{symbol}最近4个季度的营业收入、净利润、每股收益、净资产收益率、营业收入同比增长率、净利润同比增长率"
|
||||
|
||||
# 使用pywencai查询
|
||||
print(f"正在使用问财获取 {symbol} 的季报数据...")
|
||||
result = pywencai.get(question=query, perpage=10)
|
||||
|
||||
# 检查返回类型
|
||||
if result is None:
|
||||
print(f"问财未返回 {symbol} 的季报数据")
|
||||
return None
|
||||
|
||||
# 处理不同返回类型
|
||||
quarter_data = None
|
||||
|
||||
# 如果返回的是DataFrame
|
||||
if isinstance(result, pd.DataFrame):
|
||||
if result.empty:
|
||||
print(f"问财返回的DataFrame为空")
|
||||
return None
|
||||
|
||||
print(f" 问财返回DataFrame,共 {len(result)} 行数据")
|
||||
print(f" 列名: {list(result.columns)}")
|
||||
|
||||
# 将DataFrame转为字典列表,保留所有原始数据
|
||||
quarter_data = {
|
||||
'data_type': 'dataframe',
|
||||
'columns': list(result.columns),
|
||||
'records': result.head(10).to_dict('records'), # 最多取10条
|
||||
'row_count': len(result),
|
||||
'summary': f"获取到{len(result)}条季报相关数据"
|
||||
}
|
||||
|
||||
# 如果返回的是字典
|
||||
elif isinstance(result, dict):
|
||||
print(f" 问财返回字典数据")
|
||||
print(f" 字典键: {list(result.keys())}")
|
||||
|
||||
quarter_data = {
|
||||
'data_type': 'dict',
|
||||
'raw_data': result,
|
||||
'summary': f"获取到季报字典数据,包含 {len(result)} 个字段"
|
||||
}
|
||||
|
||||
# 其他类型
|
||||
else:
|
||||
print(f" 问财返回未知类型: {type(result)}")
|
||||
quarter_data = {
|
||||
'data_type': 'unknown',
|
||||
'raw_data': str(result),
|
||||
'summary': f"获取到季报数据,类型: {type(result).__name__}"
|
||||
}
|
||||
|
||||
if quarter_data:
|
||||
print(f"✅ 成功获取季报数据,将原始数据交由AI分析师处理")
|
||||
return quarter_data
|
||||
else:
|
||||
print(f"⚠️ 未能获取有效的季报数据")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"使用问财获取季报数据失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return None
|
||||
# 已删除 _get_quarter_data_from_wencai 方法
|
||||
# 季报数据现在统一由 quarterly_report_data.py 模块使用 akshare 获取
|
||||
# 获取最近8期完整季报(利润表、资产负债表、现金流量表)
|
||||
# 避免重复获取,提高效率
|
||||
|
||||
def _get_hk_financial_data(self, symbol):
|
||||
"""获取港股财务数据"""
|
||||
@@ -832,142 +762,16 @@ class StockDataFetcher:
|
||||
print(f"获取美股财务数据失败: {e}")
|
||||
return financial_data
|
||||
|
||||
def get_fund_flow_data(self, symbol):
|
||||
"""使用问财获取资金流向数据
|
||||
|
||||
Args:
|
||||
symbol: 股票代码(6位数字)
|
||||
|
||||
Returns:
|
||||
dict: 包含问财原始数据的字典
|
||||
"""
|
||||
fund_flow_data = {
|
||||
"symbol": symbol,
|
||||
"query_success": False,
|
||||
"raw_data": None, # 存储原始数据
|
||||
"data_source": "pywencai"
|
||||
}
|
||||
|
||||
# 只支持中国股票
|
||||
if not self._is_chinese_stock(symbol):
|
||||
fund_flow_data["error"] = "问财数据仅支持中国A股股票"
|
||||
return fund_flow_data
|
||||
|
||||
try:
|
||||
# 构建问句,查询近20个交易日的资金流向数据
|
||||
query = f"{symbol}近20个交易日区间资金流向、区间主力资金流向、区间涨跌幅"
|
||||
|
||||
print(f"正在使用问财查询资金流向数据: {query}")
|
||||
|
||||
# 使用pywencai查询
|
||||
result = pywencai.get(query=query, loop=True)
|
||||
|
||||
# 调试:打印result的类型
|
||||
print(f"问财返回的数据类型: {type(result)}")
|
||||
|
||||
# 处理不同类型的返回结果,统一转换为DataFrame
|
||||
df_result = None
|
||||
|
||||
if result is None:
|
||||
fund_flow_data["error"] = "问财查询返回None"
|
||||
print(f"问财查询返回None")
|
||||
elif isinstance(result, dict):
|
||||
# 如果返回的是字典,转换为DataFrame
|
||||
print(f"问财返回字典,转换为DataFrame")
|
||||
try:
|
||||
df_result = pd.DataFrame([result])
|
||||
print(f"成功转换,形状: {df_result.shape}")
|
||||
except Exception as e:
|
||||
fund_flow_data["error"] = f"无法转换为DataFrame: {str(e)}"
|
||||
print(f"转换失败: {e}")
|
||||
elif isinstance(result, pd.DataFrame):
|
||||
# 如果已经是DataFrame
|
||||
df_result = result
|
||||
print(f"问财返回DataFrame,形状: {df_result.shape}")
|
||||
else:
|
||||
fund_flow_data["error"] = f"问财返回了未知类型: {type(result)}"
|
||||
print(f"问财返回未知类型: {type(result)}")
|
||||
|
||||
# 如果成功获取到DataFrame
|
||||
if df_result is not None and not df_result.empty and len(df_result) > 0:
|
||||
# 打印列名以便调试
|
||||
print(f"问财返回的列名: {df_result.columns.tolist()}")
|
||||
|
||||
# 检查是否是嵌套结构(tableV1字段包含实际数据)
|
||||
if 'tableV1' in df_result.columns and len(df_result.columns) == 1:
|
||||
print(f"检测到嵌套结构,提取tableV1中的数据")
|
||||
table_v1_data = df_result.iloc[0]['tableV1']
|
||||
|
||||
# 检查tableV1的类型
|
||||
print(f"tableV1的类型: {type(table_v1_data)}")
|
||||
|
||||
if isinstance(table_v1_data, pd.DataFrame):
|
||||
# 如果是DataFrame,直接使用
|
||||
df_result = table_v1_data
|
||||
print(f"提取后的DataFrame形状: {df_result.shape}")
|
||||
print(f"提取后的列名: {df_result.columns.tolist()}")
|
||||
elif isinstance(table_v1_data, list) and len(table_v1_data) > 0:
|
||||
# 如果是列表,转换为DataFrame
|
||||
df_result = pd.DataFrame(table_v1_data)
|
||||
print(f"从列表转换的DataFrame形状: {df_result.shape}")
|
||||
print(f"从列表转换的列名: {df_result.columns.tolist()}")
|
||||
else:
|
||||
fund_flow_data["error"] = f"tableV1数据类型不支持: {type(table_v1_data)}"
|
||||
print(f"tableV1数据类型不支持: {type(table_v1_data)}")
|
||||
return fund_flow_data
|
||||
|
||||
# 再次检查是否有数据
|
||||
if df_result is None or df_result.empty or len(df_result) == 0:
|
||||
fund_flow_data["error"] = "提取后的数据为空"
|
||||
print(f"提取后的数据为空")
|
||||
return fund_flow_data
|
||||
|
||||
# 获取第一条记录
|
||||
data = df_result.iloc[0]
|
||||
|
||||
# 标记查询成功
|
||||
fund_flow_data["query_success"] = True
|
||||
fund_flow_data["stock_name"] = str(data.get('股票简称', data.get('name', 'N/A')))
|
||||
fund_flow_data["stock_code"] = str(data.get('股票代码', data.get('code', symbol)))
|
||||
|
||||
# 将所有数据转换为字典格式(方便AI阅读)
|
||||
raw_data_dict = {}
|
||||
for col in df_result.columns:
|
||||
value = data.get(col)
|
||||
# 转换为易读的格式
|
||||
try:
|
||||
if value is None or (isinstance(value, float) and pd.isna(value)):
|
||||
raw_data_dict[col] = "N/A"
|
||||
elif isinstance(value, (int, float)):
|
||||
# 如果是大数字(可能是金额),转换为亿元
|
||||
if abs(value) > 100000000:
|
||||
raw_data_dict[col] = f"{value} ({value/100000000:.2f}亿元)"
|
||||
else:
|
||||
raw_data_dict[col] = value
|
||||
elif isinstance(value, pd.DataFrame):
|
||||
# 如果值本身是DataFrame,跳过
|
||||
continue
|
||||
else:
|
||||
raw_data_dict[col] = str(value)
|
||||
except Exception as e:
|
||||
print(f"处理字段 {col} 时出错: {e}")
|
||||
raw_data_dict[col] = str(value)
|
||||
|
||||
fund_flow_data["raw_data"] = raw_data_dict
|
||||
fund_flow_data["columns"] = df_result.columns.tolist()
|
||||
|
||||
print(f"成功获取 {symbol} 的问财数据,共 {len(raw_data_dict)} 个字段")
|
||||
else:
|
||||
fund_flow_data["error"] = "问财查询返回空数据"
|
||||
print(f"问财查询返回空数据")
|
||||
|
||||
except Exception as e:
|
||||
fund_flow_data["error"] = f"获取资金流向数据失败: {str(e)}"
|
||||
print(f"获取资金流向数据异常: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
return fund_flow_data
|
||||
# 已删除 get_fund_flow_data 方法(使用问财)
|
||||
# 资金流向数据现在统一由 fund_flow_akshare.py 模块使用 akshare 获取
|
||||
# 获取近20个交易日的详细资金流向数据(主力、超大单、大单、中单、小单)
|
||||
# 避免重复获取,提高效率和数据质量
|
||||
#
|
||||
# 删除说明:
|
||||
# - 删除了约160行代码
|
||||
# - 删除原因:重复获取,数据格式不规整,日期范围不准确
|
||||
# - 新方案:使用 akshare 的 stock_individual_fund_flow 接口
|
||||
# - 新方案优势:数据标准化、准确获取最近20个交易日、6类资金详细分类
|
||||
|
||||
def _safe_convert(self, value):
|
||||
"""安全地转换数值"""
|
||||
|
||||
Reference in New Issue
Block a user