Python中如何爬取新浪财经的股票三表数据?
http://vip.stock.finance.sina.com.cn/usstock/balance.php?s=MSFT
这种表准确不?
这种表格是不是可以直接用 pandas 直接爬下来?
还有更好的办法吗?
Python中如何爬取新浪财经的股票三表数据?
7 回复
pandas 什么时候也可以当爬虫用了吗?是我对 pandas 有什么误解吗
import requests
import pandas as pd
from io import StringIO
import time
class SinaFinanceCrawler:
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def get_stock_code(self, symbol):
"""将股票代码转换为新浪财经格式"""
if symbol.startswith('6'):
return f'sh{symbol}'
elif symbol.startswith(('0', '3')):
return f'sz{symbol}'
else:
raise ValueError("不支持的股票代码格式")
def get_balance_sheet(self, symbol, year=2023, quarter=4):
"""获取资产负债表"""
stock_code = self.get_stock_code(symbol)
url = f'https://quotes.sina.com.cn/corp/go.php/vFD_BalanceSheet/stockid/{symbol}/ctrl/{year}/displaytype/4.phtml'
try:
response = requests.get(url, headers=self.headers, timeout=10)
response.encoding = 'gb2312'
# 使用pandas直接解析HTML表格
tables = pd.read_html(StringIO(response.text))
if len(tables) >= 2:
# 通常第二个表格是资产负债表数据
df = tables[1]
df.columns = df.iloc[0] # 设置表头
df = df[1:] # 移除重复的表头行
return df
else:
print("未找到资产负债表数据")
return None
except Exception as e:
print(f"获取资产负债表失败: {e}")
return None
def get_income_statement(self, symbol, year=2023, quarter=4):
"""获取利润表"""
stock_code = self.get_stock_code(symbol)
url = f'https://quotes.sina.com.cn/corp/go.php/vFD_ProfitStatement/stockid/{symbol}/ctrl/{year}/displaytype/4.phtml'
try:
response = requests.get(url, headers=self.headers, timeout=10)
response.encoding = 'gb2312'
tables = pd.read_html(StringIO(response.text))
if len(tables) >= 2:
df = tables[1]
df.columns = df.iloc[0]
df = df[1:]
return df
else:
print("未找到利润表数据")
return None
except Exception as e:
print(f"获取利润表失败: {e}")
return None
def get_cash_flow(self, symbol, year=2023, quarter=4):
"""获取现金流量表"""
stock_code = self.get_stock_code(symbol)
url = f'https://quotes.sina.com.cn/corp/go.php/vFD_CashFlow/stockid/{symbol}/ctrl/{year}/displaytype/4.phtml'
try:
response = requests.get(url, headers=self.headers, timeout=10)
response.encoding = 'gb2312'
tables = pd.read_html(StringIO(response.text))
if len(tables) >= 2:
df = tables[1]
df.columns = df.iloc[0]
df = df[1:]
return df
else:
print("未找到现金流量表数据")
return None
except Exception as e:
print(f"获取现金流量表失败: {e}")
return None
def get_all_statements(self, symbol, year=2023):
"""一次性获取三张财务报表"""
print(f"正在获取 {symbol} {year}年年报数据...")
balance_sheet = self.get_balance_sheet(symbol, year)
income_statement = self.get_income_statement(symbol, year)
cash_flow = self.get_cash_flow(symbol, year)
return {
'balance_sheet': balance_sheet,
'income_statement': income_statement,
'cash_flow': cash_flow
}
# 使用示例
if __name__ == "__main__":
crawler = SinaFinanceCrawler()
# 获取贵州茅台(600519)的财务报表
stock_symbol = "600519"
year = 2023
statements = crawler.get_all_statements(stock_symbol, year)
# 打印结果
for statement_name, df in statements.items():
if df is not None:
print(f"\n=== {statement_name.upper()} ===")
print(df.head())
print(f"数据形状: {df.shape}")
这个爬虫类可以直接获取新浪财经的三大财务报表。核心思路是:
- 通过分析新浪财经的URL规律,构建不同报表的请求地址
- 使用requests库获取网页内容
- 利用pandas的read_html直接解析HTML表格
- 对数据进行简单的清洗和整理
代码里我做了错误处理,确保某个表获取失败时不会影响其他表的获取。实际使用时你可以根据需要调整年份参数,或者批量获取多只股票的数据。
注意新浪财经的页面编码是gb2312,所以需要正确设置编码。另外建议在批量爬取时添加适当的延时,避免给服务器造成压力。
直接运行就能看到贵州茅台2023年的三表数据了。
可以的,tushare 就是用 pandas.read_html 直接爬的
pandas 支持表格的。
还不如爬雪球的
雪球更专业?话说如何实现一个股价提醒系统呢
做股价提醒就是按你的策略做

