京公网安备 11010802034615号
经营许可证编号:京B2-20210330
上市公司财务报表是反映企业经营状况、盈利能力、偿债能力的核心数据载体,是投资者决策、研究者分析、从业者复盘的重要依据。163网易财经作为国内权威的财经数据平台,整合了全A股、港股、美股上市公司的完整财务数据,涵盖资产负债表、利润表、现金流量表及核心财务指标,且数据更新及时、格式规范,是爬取上市公司财务数据的优选数据源。
相较于交易所官网的繁琐下载、第三方工具的付费限制,使用Python爬取163网易财经的财务报表,可实现“批量获取、自动整理、高效分析”,大幅提升数据获取效率,尤其适合需要批量处理多只股票财务数据的场景。本文将从爬取原理、环境准备、完整实操步骤、反爬应对、数据清洗与应用五个维度,手把手教你用Python爬取163网易财经上市公司财务报表,兼顾新手友好性与实操落地性,避开常见爬取误区。
在动手写代码前,需先明确163网易财经财务报表的页面结构与数据加载逻辑——这是爬取成功的关键,也是避开反爬的核心前提。
163网易财经的上市公司财务数据页面,采用固定URL规则与统一的HTML结构,便于Python解析。其核心规律如下:
URL规则:单只上市公司的财务数据页面URL格式为 http://quotes.money.163.com/hkstock/cwsj_股票代码.html(港股)、http://quotes.money.163.com/股票代码.html(A股),其中“股票代码”为上市公司的交易代码(如茅台600519、宁德时代300750),通过修改股票代码即可批量获取不同公司的数据。
数据分类:页面内包含“主要财务指标”“利润表”“资产负债表”“现金流量表”四大核心模块,每个模块对应独立的HTML表格,数据以明文形式嵌入页面,未进行复杂加密(部分动态加载数据可通过抓包获取JSON格式数据)。
数据格式:所有财务数据均为标准化格式,包含报告日期、指标名称、具体数值、单位等信息,且同一类型报表(如利润表)的表头结构一致,便于后续批量解析与整理。
本次爬取采用“请求页面→解析页面→提取数据→保存数据”的核心流程,依托Python的requests库发送HTTP请求,获取页面HTML源码,再通过BeautifulSoup库解析HTML结构,提取表格中的财务数据,最后将数据整理为Excel或CSV格式,便于后续分析使用。
需注意:163网易财经存在基础反爬机制(如User-Agent检测、请求频率限制),无需复杂的加密破解,只需模拟真实浏览器行为、控制请求频率,即可顺利爬取数据,新手可轻松上手。
爬取前需完成Python环境搭建与相关库安装,所有操作均适用于Windows、MacOS系统,步骤简单可复制。
Python版本:3.7及以上(推荐3.9版本,兼容性更好),可通过Python官网下载安装,安装时勾选“Add Python to PATH”,便于后续命令行调用。
本次爬取需用到4个核心Python库,打开命令行(Win+R输入cmd,Mac打开终端),执行以下命令批量安装:
# 安装核心库
pip install requests # 发送HTTP请求,获取页面源码
pip install beautifulsoup4 # 解析HTML页面,提取数据
pip install pandas # 整理、清洗数据,保存为Excel/CSV
pip install fake_useragent # 生成随机User-Agent,规避反爬
库功能说明:
requests:核心库,用于向163财经发送请求,获取财务数据页面的HTML源码;
beautifulsoup4:解析HTML源码,定位表格位置,提取财务指标与数值;
fake_useragent:生成随机的浏览器User-Agent,模拟真实用户访问,避免被网站识别为爬虫。
本次以爬取“贵州茅台(600519)”的财务报表为例,实现“单只股票爬取”,后续可扩展为“批量爬取多只股票”,代码全程注释,新手可直接复制运行,每一步均有详细说明。
# 导入核心库
import requests
from bs4 import BeautifulSoup
import pandas as pd
from fake_useragent import UserAgent
import time
import random
# 1. 配置目标股票信息(可修改股票代码和名称)
stock_code = "600519" # 贵州茅台股票代码
stock_name = "贵州茅台" # 股票名称,用于保存文件命名
# 2. 配置163财经财务报表页面URL(A股通用格式)
base_url = f"http://quotes.money.163.com/{stock_code}.html"
# 3. 生成随机User-Agent,模拟真实浏览器访问
ua = UserAgent()
headers = {
"User-Agent": ua.random, # 随机User-Agent,避免反爬
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Referer": "http://quotes.money.163.com/", # 模拟来源页面,提升爬取成功率
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8"
}
通过requests库发送GET请求,获取目标页面的HTML源码,加入异常处理与请求延迟,避免请求失败或触发反爬。
def get_page_html(url):
"""获取页面HTML源码,加入异常处理和请求延迟"""
try:
# 控制请求频率,随机延迟1-3秒,避免频繁请求触发反爬
time.sleep(random.uniform(1, 3))
# 发送GET请求
response = requests.get(url=url, headers=headers, timeout=10)
# 设置编码格式,避免中文乱码
response.encoding = "utf-8"
# 验证请求是否成功(状态码200表示成功)
if response.status_code == 200:
return response.text # 返回页面HTML源码
else:
print(f"请求失败,状态码:{response.status_code}")
return None
except Exception as e:
print(f"请求异常:{str(e)}")
return None
# 调用函数,获取财务报表页面HTML源码
page_html = get_page_html(base_url)
163财经的财务数据以HTML表格形式呈现,通过BeautifulSoup定位表格,提取“利润表”“资产负债表”“现金流量表”三大核心报表数据,整理为DataFrame格式。
def parse_financial_data(html):
"""解析HTML源码,提取三大财务报表数据"""
if not html:
return None, None, None
# 初始化BeautifulSoup解析器
soup = BeautifulSoup(html, "lxml")
# 定义函数,提取单个报表数据(通用函数,可复用)
def extract_table(table_id):
"""根据表格标识,提取单个报表数据"""
table = soup.find("table", id=table_id)
if not table:
return None
# 提取表头(表格第一行)
headers = [th.text.strip() for th in table.find_all("th")]
# 提取表格内容(除表头外的所有行)
rows = []
for tr in table.find_all("tr")[1:]: # 跳过表头行
row = [td.text.strip() for td in tr.find_all("td")]
if row: # 过滤空行
rows.append(row)
# 转换为DataFrame格式
df = pd.DataFrame(rows, columns=headers)
return df
# 提取三大报表数据(163财经表格标识固定,可直接使用)
income_statement = extract_table("f10-lrb-table") # 利润表
balance_sheet = extract_table("f10-zcfz-table") # 资产负债表
cash_flow = extract_table("f10-xjll-table") # 现金流量表
return income_statement, balance_sheet, cash_flow
# 调用函数,解析三大报表数据
income_df, balance_df, cash_df = parse_financial_data(page_html)
爬取的原始数据可能存在空值、空格、异常符号(如“--”“暂无数据”),需进行清洗,确保数据可用性,便于后续分析。
def clean_data(df, report_type):
"""数据清洗:处理空值、异常值,规范数据格式"""
if df is None:
print(f"{report_type}数据为空,跳过清洗")
return None
# 1. 处理空值和异常符号(将“--”“暂无数据”替换为NaN)
df = df.replace(["--", "暂无数据", ""], pd.NA)
# 2. 过滤完全空的行和列
df = df.dropna(how="all", axis=0) # 删除完全空的行
df = df.dropna(how="all", axis=1) # 删除完全空的列
# 3. 规范数值格式(将字符串类型的数值转换为浮点型,忽略非数值列)
for col in df.columns[1:]: # 跳过第一列(指标名称)
df[col] = pd.to_numeric(df[col], errors="coerce")
# 4. 添加股票名称和股票代码列,便于批量爬取时区分数据
df["股票代码"] = stock_code
df["股票名称"] = stock_name
return df
# 清洗三大报表数据
income_clean = clean_data(income_df, "利润表")
balance_clean = clean_data(balance_df, "资产负债表")
cash_clean = clean_data(cash_df, "现金流量表")
将清洗后的财务数据保存为Excel文件(支持多工作表,分别存储三大报表),也可保存为CSV格式,便于用Excel、PowerBI或Python进行后续分析。
def save_data(income_df, balance_df, cash_df):
"""保存清洗后的财务数据为Excel文件"""
# 定义保存路径(当前文件夹,以股票名称命名)
save_path = f"{stock_name}_{stock_code}_财务报表.xlsx"
# 使用ExcelWriter保存多工作表
with pd.ExcelWriter(save_path, engine="openpyxl") as writer:
if income_df is not None:
income_df.to_excel(writer, sheet_name="利润表", index=False)
if balance_df is not None:
balance_df.to_excel(writer, sheet_name="资产负债表", index=False)
if cash_df is not None:
cash_df.to_excel(writer, sheet_name="现金流量表", index=False)
print(f"✅ 数据保存成功!保存路径:{save_path}")
# 调用函数,保存数据
save_data(income_clean, balance_clean, cash_clean)
# Python爬取163网易财经上市公司财务报表(完整代码)
import requests
from bs4 import BeautifulSoup
import pandas as pd
from fake_useragent import UserAgent
import time
import random
# 配置参数
stock_code = "600519" # 股票代码
stock_name = "贵州茅台" # 股票名称
base_url = f"http://quotes.money.163.com/{stock_code}.html"
# 生成随机User-Agent
ua = UserAgent()
headers = {
"User-Agent": ua.random,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Referer": "http://quotes.money.163.com/",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8"
}
# 1. 获取页面HTML源码
def get_page_html(url):
try:
time.sleep(random.uniform(1, 3))
response = requests.get(url=url, headers=headers, timeout=10)
response.encoding = "utf-8"
if response.status_code == 200:
return response.text
else:
print(f"请求失败,状态码:{response.status_code}")
return None
except Exception as e:
print(f"请求异常:{str(e)}")
return None
# 2. 解析财务数据
def parse_financial_data(html):
if not html:
return None, None, None
soup = BeautifulSoup(html, "lxml")
def extract_table(table_id):
table = soup.find("table", id=table_id)
if not table:
return None
headers = [th.text.strip() for th in table.find_all("th")]
rows = []
for tr in table.find_all("tr")[1:]:
row = [td.text.strip() for td in tr.find_all("td")]
if row:
rows.append(row)
return pd.DataFrame(rows, columns=headers)
income_statement = extract_table("f10-lrb-table")
balance_sheet = extract_table("f10-zcfz-table")
cash_flow = extract_table("f10-xjll-table")
return income_statement, balance_sheet, cash_flow
# 3. 数据清洗
def clean_data(df, report_type):
if df is None:
print(f"{report_type}数据为空,跳过清洗")
return None
df = df.replace(["--", "暂无数据", ""], pd.NA)
df = df.dropna(how="all", axis=0)
df = df.dropna(how="all", axis=1)
for col in df.columns[1:]:
df[col] = pd.to_numeric(df[col], errors="coerce")
df["股票代码"] = stock_code
df["股票名称"] = stock_name
return df
# 4. 保存数据
def save_data(income_df, balance_df, cash_df):
save_path = f"{stock_name}_{stock_code}_财务报表.xlsx"
with pd.ExcelWriter(save_path, engine="openpyxl") as writer:
if income_df is not None:
income_df.to_excel(writer, sheet_name="利润表", index=False)
if balance_df is not None:
balance_df.to_excel(writer, sheet_name="资产负债表", index=False)
if cash_df is not None:
cash_df.to_excel(writer, sheet_name="现金流量表", index=False)
print(f"✅ 数据保存成功!保存路径:{save_path}")
# 主函数:执行爬取流程
def main():
print(f"开始爬取{stock_name}({stock_code})财务报表...")
page_html = get_page_html(base_url)
income_df, balance_df, cash_df = parse_financial_data(page_html)
income_clean = clean_data(income_df, "利润表")
balance_clean = clean_data(balance_df, "资产负债表")
cash_clean = clean_data(cash_df, "现金流量表")
save_data(income_clean, balance_clean, cash_clean)
print("爬取完成!")
# 执行主函数
if __name__ == "__main__":
main()
若需爬取多只上市公司财务报表,只需将股票代码和名称整理为列表,循环调用主函数即可,核心修改代码如下:
# 批量爬取多只股票财务报表
stock_list = [
{"code": "600519", "name": "贵州茅台"},
{"code": "300750", "name": "宁德时代"},
{"code": "000333", "name": "美的集团"},
{"code": "601933", "name": "永辉超市"}
]
# 循环爬取每只股票
for stock in stock_list:
stock_code = stock["code"]
stock_name = stock["name"]
base_url = f"http://quotes.money.163.com/{stock_code}.html"
main() # 调用主函数,爬取单只股票数据
time.sleep(random.uniform(2, 4)) # 批量爬取时,增加延迟,避免反爬
爬取过程中,新手容易遇到请求失败、数据提取为空、被反爬限制等问题,以下5个注意事项,帮你规避风险,确保爬取顺利。
163网易财经对单一IP的请求频率有一定限制,若频繁发送请求,会被识别为爬虫,导致IP被临时封禁(表现为请求状态码403)。解决方案:在请求之间加入随机延迟(1-3秒),批量爬取时延迟可增加至2-4秒,模拟真实用户浏览行为,避免触发反爬机制。
若仅使用默认请求头,网站会识别为爬虫,拒绝返回数据。解决方案:使用fake_useragent库生成随机User-Agent,同时添加Referer字段(模拟页面来源),完善请求头信息,提升爬取成功率,代码中已集成该逻辑,无需额外修改。
部分上市公司的财务数据采用JavaScript动态加载(如部分港股数据),直接爬取HTML源码无法获取数据。解决方案:通过浏览器开发者工具(F12)抓包,找到动态加载的JSON接口,直接请求接口获取数据,无需解析HTML,具体可参考163财经的接口规律(如主要财务指标的JSON接口)。
爬取的原始数据中,常见“--”“暂无数据”等异常符号,若不清洗,会导致后续数值分析失败。解决方案:代码中已集成空值、异常值处理逻辑,若遇到特殊异常符号,可在clean_data函数中添加替换规则(如df = df.replace("异常符号", pd.NA))。
163网易财经的财务数据为公开信息,但爬取时需遵守网站robots协议,不进行恶意爬取(如高频请求、批量爬取大量数据),不将爬取的数据用于商业用途,仅用于个人学习、研究,避免违反相关法律法规和网站使用条款。
爬取并清洗后的财务报表数据,可用于多种场景,无论是个人学习、投资分析,还是数据分析实操,都具有很高的实用价值,结合Python可实现更深度的分析:
通过pandas计算核心财务指标,如净资产收益率(ROE)、毛利率、资产负债率、净利润增长率等,分析企业的盈利能力、偿债能力、成长能力。例如,计算贵州茅台的毛利率,判断其产品竞争力;计算资产负债率,评估其财务风险,这也是财报分析的核心环节之一。
批量爬取同行业多家上市公司的财务数据,对比其核心指标,筛选优质企业。例如,爬取白酒行业(茅台、五粮液、泸州老窖)的财务报表,对比三者的净利润、毛利率,分析行业竞争格局。
结合matplotlib、seaborn等库,将财务数据可视化,如绘制净利润趋势图、资产负债结构饼图、现金流变化折线图,直观呈现企业经营状况,让分析结果更具说服力,这也契合163财经新版页面的图表化展示趋势。
对于数据分析新手而言,爬取财务报表是练习Python爬虫、数据清洗、数据处理的优质案例,涵盖requests、BeautifulSoup、pandas等核心库的使用,同时可熟悉财务数据的结构,提升数据分析实操能力,为后续从事金融数据分析打下基础。
相较于传统的手动下载、复制粘贴,使用Python爬取163网易财经上市公司财务报表,核心优势在于“高效、批量、可复用”——无需手动操作,即可快速获取单只或多只股票的完整财务数据,自动整理清洗,大幅节省时间成本;同时,163财经的数据共识性高、格式规范,爬取难度低,适合新手入门实操。
本文的实操代码可直接复制运行,修改股票代码即可适配不同上市公司,批量爬取扩展简单,兼顾实用性与易懂性。需要注意的是,爬取过程中需遵守反爬规则与合规要求,控制请求频率,模拟真实用户行为,避免出现IP封禁等问题。
无论是金融从业者、投资者,还是数据分析新手,掌握Python爬取163财经财务报表的方法,都能让财务数据获取与分析更高效,让数据成为决策、学习、研究的有力支撑,真正发挥数据的价值。

在数字经济飞速发展的今天,数据分析已从“辅助工具”升级为“核心竞争力”,渗透到商业、科技、民生、金融等各个领域。无论是全 ...
2026-03-11上市公司财务报表是反映企业经营状况、盈利能力、偿债能力的核心数据载体,是投资者决策、研究者分析、从业者复盘的重要依据。16 ...
2026-03-11数字化浪潮下,数据已成为企业生存发展的核心资产,而数据思维,正是CDA(Certified Data Analyst)数据分析师解锁数据价值、赋 ...
2026-03-11线性回归是数据分析中最常用的预测与关联分析方法,广泛应用于销售额预测、风险评估、趋势分析等场景(如前文销售额预测中的多元 ...
2026-03-10在SQL Server安装与配置的实操中,“服务名无效”是最令初学者头疼的高频问题之一。无论是在命令行执行net start启动服务、通过S ...
2026-03-10在数据驱动业务的当下,CDA(Certified Data Analyst)数据分析师的核心价值,不仅在于解读数据,更在于搭建一套科学、可落地的 ...
2026-03-10在企业经营决策中,销售额预测是核心环节之一——无论是库存备货、营销预算制定、产能规划,还是战略布局,都需要基于精准的销售 ...
2026-03-09金融数据分析的核心价值,是通过挖掘数据规律、识别风险、捕捉机会,为投资决策、风险控制、业务优化提供精准支撑——而这一切的 ...
2026-03-09在数据驱动决策的时代,CDA(Certified Data Analyst)数据分析师的核心工作,是通过数据解读业务、支撑决策,而指标与指标体系 ...
2026-03-09在数据处理的全流程中,数据呈现与数据分析是两个紧密关联却截然不同的核心环节。无论是科研数据整理、企业业务复盘,还是日常数 ...
2026-03-06在数据分析、数据预处理场景中,dat文件是一种常见的二进制或文本格式数据文件,广泛应用于科研数据、工程数据、传感器数据等领 ...
2026-03-06在数据驱动决策的时代,CDA(Certified Data Analyst)数据分析师的核心价值,早已超越单纯的数据清洗与统计分析,而是通过数据 ...
2026-03-06在教学管理、培训数据统计、课程体系搭建等场景中,经常需要对课时数据进行排序并实现累加计算——比如,按课程章节排序,累加各 ...
2026-03-05在数据分析场景中,环比是衡量数据短期波动的核心指标——它通过对比“当前周期与上一个相邻周期”的数据,直观反映指标的月度、 ...
2026-03-05数据治理是数字化时代企业实现数据价值最大化的核心前提,而CDA(Certified Data Analyst)数据分析师作为数据全生命周期的核心 ...
2026-03-05在实验检测、质量控制、科研验证等场景中,“方法验证”是确保检测/分析结果可靠、可复用的核心环节——无论是新开发的检测方法 ...
2026-03-04在数据分析、科研实验、办公统计等场景中,我们常常需要对比两组数据的整体差异——比如两种营销策略的销售额差异、两种实验方案 ...
2026-03-04在数字化转型进入深水区的今天,企业对数据的依赖程度日益加深,而数据治理体系则是企业实现数据规范化、高质量化、价值化的核心 ...
2026-03-04在深度学习,尤其是卷积神经网络(CNN)的实操中,转置卷积(Transposed Convolution)是一个高频应用的操作——它核心用于实现 ...
2026-03-03在日常办公、数据分析、金融理财、科研统计等场景中,我们经常需要计算“平均值”来概括一组数据的整体水平——比如计算月度平均 ...
2026-03-03