简介:本文面向有数据抓取需求的开发者,介绍如何用Python获取A股财务指标与收盘价,并计算“每股净资产、每股未分配利润、每股资本公积金之和与股价的比值”。文章给出可运行的实现思路、关键注意事项及结果导出方法,帮助读者快速完成数据采集与指标计算。
在A股市场分析中,投资者经常希望用一个相对简单的指标来衡量个股的“账面价值厚度”或“安全边际”。一种常见思路是:将每股净资产、每股未分配利润、每股资本公积金三者相加,再除以当前股价,得到一个大致的比值。该比值越高,通常意味着每股所对应的账面积累相对于市场价格越厚。
从财务角度看,这三个指标分别代表不同层面的股东权益积累:
将三者相加后再与股价比较,可以看作一种粗略的“账面价值/市场价格”分析方式。不过需要注意,这一公式在财务口径上存在重复计算问题,后文会专门说明。
要完成这项计算,需要获取两类数据:
在Python生态中,可以使用公开的金融数据接口来完成数据获取,而不需要从零编写网页爬虫。常见做法是调用免费的数据服务库,传入股票代码和起止年份,直接返回结构化的财务指标表与日线行情表。
整体实现流程如下:
下面给出一段简化但可运行的示例代码。代码中使用了通用的金融数据接口,具体库名和调用方式可根据实际环境替换为可用数据源。
import datetime as dtimport pandas as pd# 假设环境中已安装可用的金融数据接口库import fin_data_api as fdCODES = ["600519", "000001", "601318"] # 替换为目标股票代码def get_latest_indicators(code):"""获取最近一期财务指标。返回:报告期、每股净资产、每股未分配利润、每股资本公积金。"""year = str(dt.date.today().year - 1)df = fd.get_financial_indicator(symbol=code, start_year=year)df = df.sort_values("报告期")row = df.iloc[-1] # 取最近一期return (str(row["报告期"]),float(row["每股净资产"]),float(row["每股未分配利润"]),float(row["每股资本公积金"]),)def get_latest_close(code):"""获取最近收盘价。"""start = (dt.date.today() - dt.timedelta(days=20)).strftime("%Y%m%d")df = fd.get_daily_price(symbol=code, start_date=start)return str(df.iloc[-1]["日期"]), float(df.iloc[-1]["收盘价"])rows = []for code in CODES:try:report_date, nav, undistributed, capital_reserve = get_latest_indicators(code)trade_date, close_price = get_latest_close(code)ratio = round((nav + undistributed + capital_reserve) / close_price, 4)rows.append({"代码": code,"报告期": report_date,"每股净资产": nav,"每股未分配利润": undistributed,"每股资本公积金": capital_reserve,"收盘日期": trade_date,"收盘价": close_price,"比值": ratio,})except Exception as exc:print(f"{code} 获取失败:{exc}")result_df = pd.DataFrame(rows)print(result_df.to_string(index=False))result_df.to_excel("a_share_ratio_result.xlsx", index=False)
上述代码的核心逻辑是:
get_latest_indicators 获取财务指标,并按报告期排序后取最新一条。get_latest_close 获取最近一段时间的日线数据,并取最后一个交易日收盘价。pandas 汇总结果,并同时输出到控制台和Excel文件。在实际使用中,免费金融数据接口的稳定性与字段命名可能因版本变化而不同。开发时应注意以下几点:
字段名称兼容性:不同数据源对相同财务指标可能有不同命名,例如“每股净资产”可能带有“调整前”或“调整后”等后缀。代码中应做字段存在性检查或别名映射。
报告期选择:财务指标通常按季度发布,同一时间可能存在多期数据。应明确取“最新报告期”而不是自然年最后一天。
行情复权处理:如果用于与财务数据对比,建议使用不复权价格。复权价格会因分红送转改变历史价格,进而影响比值计算的可比性。
异常处理:部分股票可能因停牌、数据缺失或字段异常导致获取失败。应当捕获异常并记录,而不是中断整个批量任务。
计算结果中的比值可以用于横向比较不同股票,但必须理解其局限性。
每股净资产本身已经包含了未分配利润和资本公积金。以常见财务报表结构为例:
每股净资产 = 股本 + 资本公积 + 盈余公积 + 未分配利润 + 其他综合收益等
因此,如果再将“每股未分配利润”和“每股资本公积金”与“每股净资产”相加,相当于把这两项重复计算了一次。更合理的修正方式可能是:
该比值只反映账面价值与市场价格的关系,并不能覆盖企业盈利能力、成长性、行业周期、管理层质量等关键因素。某些行业天然具有较低市净率,例如银行、地产;而成长型行业可能长期维持较低比值。因此该指标只能作为辅助观察维度之一。
最新一期财报数据通常滞后于当前行情。例如,第三季度报告可能在10月底才披露,而股价已经反映了之后的市场信息。因此计算出来的比值是“历史财务数据”与“当前价格”的组合,不能视为实时估值指标。
如果要将上述脚本用于持续跟踪,可以考虑以下改进方向:
将脚本部署到定时任务中,每日收盘后自动运行,生成最新的比值表并保存到本地或对象存储中,便于后续分析。
除了导出Excel,还可以将结果写入数据库。每次运行保留时间戳,形成历史序列,观察比值随时间的变化趋势。
对于批量获取失败的情况,记录详细日志。可接入通用监控告警能力,当失败率超过阈值时提醒维护人员。
免费数据接口可能出现限流或临时不可用。可以配置多个数据源作为备用,主源失败时自动切换,提高任务稳定性。
本文介绍了如何用Python批量获取A股股票的每股净资产、每股未分配利润、每股资本公积金以及最新收盘价,并计算目标比值。通过结构化数据接口替代手写爬虫,可以显著降低开发复杂度,提高代码可维护性。
在实践过程中,需要重点关注财务指标字段差异、报告期选择、行情复权方式以及公式本身的重复计算问题。该比值可以作为观察个股账面价值与市场价格关系的辅助指标,但不应作为唯一决策依据。通过工程化改造,可以将一次性脚本扩展为可持续运行的数据跟踪任务。