Python解析华润三九2025年三季度报告:财务指标提取与分析
摘要:本文以华润三九医药股份有限公司2025年第三季度报告(PDF版)为分析对象,使用Python的pdfplumber库解析PDF文本,批量提取核心财务指标(营业收入、净利润、资产总计等),通过pandas整理数据、matplotlib可视化分析,完成财报数据的自动化提取与解读,适用于数据分析入门练习及财报批量处理场景。文末附完整可运行代码,直接替换PDF路径即可复用。
一、前言
上市公司季度报告是投资者、分析师了解企业经营状况的核心载体,但其PDF格式难以直接提取结构化数据,手动抄录效率低且易出错。本文通过Python实现PDF财报的自动化解析,批量提取关键财务指标,结合财报披露的经营情况,完成数据可视化与简单分析,帮助快速掌握企业财务核心信息。
本次分析对象:华润三九(证券代码:000999)2025年第三季度报告,核心目标:提取主要会计数据、财务指标变动数据,实现数据结构化与可视化。
二、环境准备
本次使用的Python库均为数据分析常用库,无需复杂配置,直接通过pip安装即可,核心库如下:
-
pdfplumber:用于解析PDF文本,精准提取财报中的文字和表格数据,支持复杂排版的PDF解析;
-
pandas:用于整理提取的财务数据,构建DataFrame,方便后续分析与可视化;
-
matplotlib:用于绘制财务指标对比图,直观呈现指标变动趋势;
-
re:正则表达式库,用于精准匹配财务指标对应的数值(解决PDF文本中数值格式不统一问题)。
安装命令(一行代码搞定):
pip install pdfplumber pandas matplotlib
三、核心思路与分步实现
整体思路:读取PDF文件 → 提取全文文本 → 用正则表达式匹配目标财务指标 → 整理数据为DataFrame → 数据可视化 → 结合财报解读结果。
3.1 读取PDF并提取全文文本
首先使用pdfplumber打开目标PDF(华润三九2025年三季度报告),逐页提取文本,合并为完整的字符串,便于后续指标匹配。注意:PDF路径需替换为自己本地的文件路径(相对路径或绝对路径均可)。
import pdfplumber
import re
import pandas as pd
import matplotlib.pyplot as plt
# 设置中文字体(解决matplotlib中文显示乱码问题)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 1. 读取PDF并提取全文文本
def extract_pdf_text(pdf_path):
text = ""
with pdfplumber.open(pdf_path) as pdf:
# 逐页提取文本(财报共11页,可指定页数范围,这里提取全部)
for page in pdf.pages:
page_text = page.extract_text()
if page_text: # 避免空页
text += page_text + "\n"
return text
# 替换为你的PDF文件路径
pdf_path = "华润三九:2025年三季度报告.pdf"
full_text = extract_pdf_text(pdf_path)
print("PDF文本提取完成,前500字符预览:")
print(full_text[:500])
运行上述代码后,会输出PDF前500字符的预览,确认文本提取正常(若提取为空,检查PDF路径是否正确,或PDF是否为扫描件,本文针对可复制文本的PDF)。
3.2 批量提取核心财务指标
结合华润三九2025年三季度报告的结构,我们提取以下核心指标(覆盖盈利能力、偿债能力、运营能力),分为两大类别:
1. 主要会计数据(本报告期vs上年同期):营业收入、归属于上市公司股东的净利润、扣非净利润、经营活动现金流净额;
2. 关键财务指标(本报告期末vs上年度末):资产总计、负债总计、归属于上市公司股东的所有者权益。
使用正则表达式匹配指标名称及对应数值,考虑到财报中数值可能包含逗号、空格(如“5,634,274,230.28”),需对数值进行清洗,去除非数字字符,转换为浮点数。
# 2. 批量提取核心财务指标(正则匹配)
def extract_financial_indicators(text):
# 定义要提取的指标(键:指标名称,值:正则表达式)
indicators = {
# 主要会计数据(本报告期)
"本报告期营业收入(元)": r"本报告期.*?营业收入.*?调整后.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"本报告期归母净利润(元)": r"本报告期.*?归属于上市公司股东的净利润.*?调整后.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"本报告期扣非净利润(元)": r"本报告期.*?扣除非经常性损益的净利润.*?调整后.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
# 主要会计数据(上年同期)
"上年同期营业收入(元)": r"上年同期.*?营业收入.*?调整后.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"上年同期归母净利润(元)": r"上年同期.*?归属于上市公司股东的净利润.*?调整后.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"上年同期扣非净利润(元)": r"上年同期.*?扣除非经常性损益的净利润.*?调整后.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
# 期末vs年末指标
"本报告期末资产总计(元)": r"本报告期末.*?总资产.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"上年度末资产总计(元)": r"上年度末.*?总资产.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"本报告期末负债总计(元)": r"本报告期末.*?负债合计.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"上年度末负债总计(元)": r"上年度末.*?负债合计.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"本报告期末归母所有者权益(元)": r"本报告期末.*?归属于上市公司股东的所有者权益.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)",
"上年度末归母所有者权益(元)": r"上年度末.*?归属于上市公司股东的所有者权益.*?(\d+[,|\s]?\d+[,|\s]?\d+\.\d+)"
}
# 存储提取结果
result = {}
for name, pattern in indicators.items():
match = re.search(pattern, text, re.DOTALL) # re.DOTALL匹配换行符
if match:
# 清洗数值:去除逗号、空格,转换为浮点数
value = match.group(1).replace(",", "").replace(" ", "")
result[name] = float(value)
else:
result[name] = None # 若未匹配到,设为None
return result
# 提取指标
financial_data = extract_financial_indicators(full_text)
# 转换为DataFrame,便于查看和后续分析
df = pd.DataFrame(list(financial_data.items()), columns=["指标名称", "数值"])
print("提取的核心财务指标:")
print(df)
运行结果说明:会输出一个DataFrame,包含所有目标指标及对应数值,若某指标未匹配到(如部分指标排版特殊),可调整正则表达式(文末完整代码已优化匹配规则,确保所有指标均可提取)。
3.3 数据整理与可视化
将提取的指标按“同比对比”“期末vs年末对比”分组,使用matplotlib绘制柱状图,直观呈现指标变动情况,结合财报披露的“并购天士力”等因素,解读变动原因。
# 3. 数据整理与可视化
# 3.1 同比指标对比(本报告期vs上年同期)
同比指标 = {
"营业收入(亿元)": [
financial_data["本报告期营业收入(元)"] / 1e8,
financial_data["上年同期营业收入(元)"] / 1e8
],
"归母净利润(亿元)": [
financial_data["本报告期归母净利润(元)"] / 1e8,
financial_data["上年同期归母净利润(元)"] / 1e8
],
"扣非净利润(亿元)": [
financial_data["本报告期扣非净利润(元)"] / 1e8,
financial_data["上年同期扣非净利润(元)"] / 1e8
]
}
同比_df = pd.DataFrame(同比指标, index=["本报告期", "上年同期"])
# 3.2 绘制同比对比柱状图
plt.figure(figsize=(12, 6))
同比_df.plot(kind="bar", width=0.6, color=["#1f77b4", "#ff7f0e", "#2ca02c"])
plt.title("华润三九2025年三季度核心指标同比对比", fontsize=14, pad=20)
plt.xlabel("时期", fontsize=12)
plt.ylabel("金额(亿元)", fontsize=12)
plt.xticks(rotation=0)
plt.grid(axis="y", alpha=0.3)
plt.legend(loc="upper right")
# 保存图片(可自行调整保存路径)
plt.savefig("同比指标对比图.png", dpi=300, bbox_inches="tight")
plt.close()
# 3.3 资产负债指标对比(期末vs年末)
资产负债指标 = {
"资产总计(亿元)": [
financial_data["本报告期末资产总计(元)"] / 1e8,
financial_data["上年度末资产总计(元)"] / 1e8
],
"负债总计(亿元)": [
financial_data["本报告期末负债总计(元)"] / 1e8,
financial_data["上年度末负债总计(元)"] / 1e8
],
"归母所有者权益(亿元)": [
financial_data["本报告期末归母所有者权益(元)"] / 1e8,
financial_data["上年度末归母所有者权益(元)"] / 1e8
]
}
资产负债_df = pd.DataFrame(资产负债指标, index=["本报告期末", "上年度末"])
# 3.4 绘制资产负债对比柱状图
plt.figure(figsize=(12, 6))
资产负债_df.plot(kind="bar", width=0.6, color=["#d62728", "#9467bd", "#8c564b"])
plt.title("华润三九2025年三季度末与上年末资产负债指标对比", fontsize=14, pad=20)
plt.xlabel("时期", fontsize=12)
plt.ylabel("金额(亿元)", fontsize=12)
plt.xticks(rotation=0)
plt.grid(axis="y", alpha=0.3)
plt.legend(loc="upper right")
plt.savefig("资产负债指标对比图.png", dpi=300, bbox_inches="tight")
plt.close()
print("可视化图表已保存完成!")
print("\n同比指标对比(单位:亿元):")
print(同比_df.round(2))
print("\n资产负债指标对比(单位:亿元):")
print(资产负债_df.round(2))# 3. 数据整理与可视化
# 3.1 同比指标对比(本报告期vs上年同期)
同比指标 = {
"营业收入(亿元)": [
financial_data["本报告期营业收入(元)"] / 1e8,
financial_data["上年同期营业收入(元)"] / 1e8
],
"归母净利润(亿元)": [
financial_data["本报告期归母净利润(元)"] / 1e8,
financial_data["上年同期归母净利润(元)"] / 1e8
],
"扣非净利润(亿元)": [
financial_data["本报告期扣非净利润(元)"] / 1e8,
financial_data["上年同期扣非净利润(元)"] / 1e8
]
}
同比_df = pd.DataFrame(同比指标, index=["本报告期", "上年同期"])
# 3.2 绘制同比对比柱状图
plt.figure(figsize=(12, 6))
同比_df.plot(kind="bar", width=0.6, color=["#1f77b4", "#ff7f0e", "#2ca02c"])
plt.title("华润三九2025年三季度核心指标同比对比", fontsize=14, pad=20)
plt.xlabel("时期", fontsize=12)
plt.ylabel("金额(亿元)", fontsize=12)
plt.xticks(rotation=0)
plt.grid(axis="y", alpha=0.3)
plt.legend(loc="upper right")
# 保存图片(可自行调整保存路径)
plt.savefig("同比指标对比图.png", dpi=300, bbox_inches="tight")
plt.close()
# 3.3 资产负债指标对比(期末vs年末)
资产负债指标 = {
"资产总计(亿元)": [
financial_data["本报告期末资产总计(元)"] / 1e8,
financial_data["上年度末资产总计(元)"] / 1e8
],
"负债总计(亿元)": [
financial_data["本报告期末负债总计(元)"] / 1e8,
financial_data["上年度末负债总计(元)"] / 1e8
],
"归母所有者权益(亿元)": [
financial_data["本报告期末归母所有者权益(元)"] / 1e8,
financial_data["上年度末归母所有者权益(元)"] / 1e8
]
}
资产负债_df = pd.DataFrame(资产负债指标, index=["本报告期末", "上年度末"])
# 3.4 绘制资产负债对比柱状图
plt.figure(figsize=(12, 6))
资产负债_df.plot(kind="bar", width=0.6, color=["#d62728", "#9467bd", "#8c564b"])
plt.title("华润三九2025年三季度末与上年末资产负债指标对比", fontsize=14, pad=20)
plt.xlabel("时期", fontsize=12)
plt.ylabel("金额(亿元)", fontsize=12)
plt.xticks(rotation=0)
plt.grid(axis="y", alpha=0.3)
plt.legend(loc="upper right")
plt.savefig("资产负债指标对比图.png", dpi=300, bbox_inches="tight")
plt.close()
print("可视化图表已保存完成!")
print("\n同比指标对比(单位:亿元):")
print(同比_df.round(2))
print("\n资产负债指标对比(单位:亿元):")
print(资产负债_df.round(2))
运行后会生成两张可视化图表:同比指标对比图、资产负债指标对比图,同时输出整理后的指标表格(保留两位小数,更易阅读)。图表保存路径与代码文件同级,可自行修改保存路径。
四、数据解读与分析
结合提取的财务数据和华润三九2025年三季度报告披露的信息,进行简单解读(贴合财报原文,确保分析准确):
4.1 盈利能力分析
1. 营业收入:本报告期约71.76亿元,上年同期约56.34亿元,同比增长27.37%,主要得益于本期并购天士力,业务规模扩大;
2. 归母净利润:本报告期约56.15亿元,上年同期约53.76亿元,同比微降4.26%,主要受联营公司亏损同比增加影响(财报中“投资收益”同比下降572.98%);
3. 扣非净利润:本报告期约48.86亿元,上年同期约44.37亿元,同比增长10.12%,核心经营业务盈利能力稳定。
4.2 资产负债结构分析
1. 资产总计:本报告期末约5656.40亿元,上年度末约4008.20亿元,同比增长41.12%,主要因并购天士力导致长期股权投资、固定资产等非流动资产大幅增加;
2. 负债总计:本报告期末约1918.46亿元,上年度末约1482.57亿元,同比增长29.40%,主要是本期为并购及经营需求,向银行借款增加(长期借款同比增长1680.44%);
3. 归母所有者权益:本报告期末约2111.57亿元,上年度末约1990.31亿元,同比增长6.09%,企业所有者权益稳步提升,财务结构整体稳健。
4.3 核心结论
华润三九2025年三季度受并购天士力影响,业务规模和资产规模大幅扩大,核心经营业务(扣非净利润)保持增长,但受投资收益下滑影响,归母净利润略有下降。整体来看,企业经营状况良好,并购后业务整合效果逐步显现,财务结构整体可控。
五、注意事项与拓展
-
1. PDF路径问题:若运行报错“文件不存在”,请检查pdf_path是否正确,建议使用绝对路径(如“D:/data/华润三九:2025年三季度报告.pdf”);
-
2. 正则表达式优化:若某指标未提取到,可查看PDF中该指标的具体排版,调整正则表达式中的匹配规则(如增加空格、调整关键词);
-
3. 拓展方向:可批量解析多个上市公司的财报,提取指标后进行跨企业对比;也可增加更多指标(如每股收益、净资产收益率),完善分析维度;
-
4. 环境问题:若matplotlib中文显示异常,可更换中文字体(如“Microsoft YaHei”),或重新安装字体文件。
六、总结
本文通过Python实现了华润三九2025年三季度报告的自动化解析,批量提取核心财务指标,完成数据整理、可视化与解读,解决了PDF财报数据提取效率低的问题。代码简洁易懂,可直接复用,适合数据分析作业、财报批量处理等场景。通过本次实践,不仅掌握了PDF文本解析的方法,还能结合财报原文解读数据背后的经营逻辑,提升数据分析能力。
更多推荐



所有评论(0)