东方财富网股票数据爬取实战:从接口分析到数据存储
在金融数据分析领域,获取准确、全面的股票基础数据是开展后续分析的前提。本文将详细介绍如何通过Python爬取东方财富网的A股相关数据,涵盖接口分析、数据解析、循环爬取及CSV文件存储全流程,帮助读者掌握金融数据爬取的核心思路与实现方法。
一、技术选型与前期准备
1. 核心库说明
本次爬取任务主要依赖以下Python库:
requests:发送HTTP请求,获取网页/接口数据;re:正则表达式处理,清洗接口返回的非标准JSON数据;pandas:数据结构化存储与CSV文件读写。
2. 环境配置
确保已安装对应依赖库,执行以下命令:
python
pip install requests pandas
二、接口分析与请求构造
1. 目标接口定位
东方财富网的股票列表数据通过接口返回,核心接口格式如下:
https://7.push2.eastmoney.com/api/qt/clist/get?
cb=jQueryxxx&pn={页码}&pz=20&po=1&np=1&ut=xxx&fltt=2&invt=2&wbp2u=xxx&fid={分类参数}&fields={字段参数}&_=时间戳
关键参数说明:
pn:页码,控制分页爬取;pz:每页条数,示例中设为20;fid:股票分类标识(如沪深京A股、创业板等);fields:需要获取的字段(如代码f12、名称f14、最新价f2等)。
2. 请求头配置
为模拟浏览器请求,避免被反爬,需配置User-Agent和Cookie(Cookie可从浏览器开发者工具中获取):
python
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Cookie": "qgqp_b_id=xxx; websitepoptg_api_time=xxx; ..."
}
三、核心代码实现
1. 定义股票分类参数
首先定义需要爬取的股票分类及对应的fid参数,便于循环爬取:
python
aa = {
"沪深京A股": "f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048",
"上证A股": "f3&fs=m:1+t:2,m:1+t:23",
"深证A股": "f3&fs=m:0+t:6,m:0+t:80",
"北证A股": "f3&fs=m:0+t:81+s:2048",
"新股": "f26&fs=m:0+f:8,m:1+f:8",
"创业板": "f3&fs=m:0+t:80",
"科创板": "f3&fs=m:1+t:23",
"沪股通": "f26&fs=b:BK0707",
"深股通": "f26&fs=b:BK0804",
"B股": "f3&fs=m:0+t:7,m:1+t:3",
"风险警示板": "f3&fs=m:0+f:4,m:1+f:4",
}
2. 接口数据获取函数
封装get_html函数,负责发送请求、清洗数据并返回结构化字典:
python
def get_html(aa, page):
# 构造完整请求URL
url = f"https://7.push2.eastmoney.com/api/qt/clist/get?" \
f"cb=jQuery112409467675731682619_1703939377395&pn={page}&pz=20&po=1&np=1" \
f"&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid={aa}&fields=f1," \
f"f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18," \
f"f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1703939377396"
# 发送GET请求
response = requests.get(url, headers=header).text
# 清洗jQuery包裹的非标准JSON数据
left_data = re.search(r'^.*?(?=\()', response).group()
data = re.sub(left_data + '\(', '', response)
data = re.sub('\);', '', data)
# 转换为Python字典
data = eval(data)
return data
3. 循环爬取所有分类数据
遍历所有股票分类,分页爬取数据并整合到总DataFrame中:
python
# 初始化总数据容器
all_df = pd.DataFrame(columns=["代码", "名称", "最新价", "开盘价", "收盘价"])
null = "null"
for category in aa.keys():
page = 0
while True:
page += 1
data = get_html(aa[category], page)
# 数据非空则解析存储
if data['data'] != null:
print(f"正在爬取 {category} 第 {page} 页")
df = data['data']['diff']
for index in df:
all_df = all_df.append({
"代码": index["f12"],
"名称": index['f14'],
"最新价": index['f2'],
"开盘价": index['f17'],
"收盘价": index['f18']
}, ignore_index=True)
else:
# 数据为空则结束该分类爬取
break
4. 数据存储与预览
将爬取的总数据保存为CSV文件,并读取预览前50行:
python
# 保存为CSV文件(解决中文乱码用gb18030编码)
all_df.to_csv("股票数据.csv", index=False, encoding='gb18030')
# 读取CSV文件
all_df = pd.read_csv("股票数据.csv", encoding='gb18030')
# 预览数据
print("前50行数据:")
print(all_df.head(50))
四、关键问题与优化思路
1. 数据清洗关键点
接口返回的是jQuery包裹的JSON数据,需通过正则去掉前缀(jQueryxxx()和后缀();),再用eval转换为字典,也可改用json.loads提升安全性。
2. 反爬策略应对
- 配置真实的
User-Agent和Cookie,模拟浏览器行为; - 可添加请求延时(
time.sleep(1)),避免高频请求被封IP; - 分页爬取时设置合理的每页条数,避免单次请求数据量过大。
3. 性能优化
-
替换
DataFrame.append为列表存储后批量转换(append效率低):python# 优化方案:先存列表,再转DataFrame data_list = [] for index in df: data_list.append({ "代码": index["f12"], "名称": index['f14'], "最新价": index['f2'], "开盘价": index['f17'], "收盘价": index['f18'] }) all_df = pd.DataFrame(data_list) -
多线程/多进程爬取(需控制并发数),提升爬取效率。
4. 异常处理
添加try-except捕获请求异常(如网络中断、接口返回异常),避免程序崩溃:
python
def get_html(aa, page):
try:
response = requests.get(url, headers=header, timeout=10).text
# 后续清洗逻辑
except Exception as e:
print(f"第{page}页请求失败:{e}")
return {"data": null}
五、总结
本文通过实战案例讲解了东方财富网股票数据的爬取流程,核心在于接口参数分析、非标准JSON数据清洗、分页循环爬取及Pandas数据处理。该思路可扩展到其他金融数据爬取场景,同时需注意遵守网站robots协议,合理合规获取数据。