手把手教学!Python爬虫爬取股票实时数据,开盘价+收盘价+涨幅,绘制K线图分析走势
前言:对于刚入门Python爬虫的小伙伴来说,爬取股票数据是一个非常好的实战案例——数据公开易获取、需求明确(开盘价、收盘价、涨幅等核心指标),还能结合数据可视化绘制K线图,实现“爬取-分析-可视化”全流程实战。本文全程手把手,从环境搭建、爬虫编写,到数据存储、K线图绘制,每一步都附完整代码+详细注释,新手跟着敲就能跑通,无多余复杂概念,纯实战落地!
提示:本文爬取的是公开的股票实时行情数据,严格遵守网站robots协议,仅用于学习交流,不涉及商业用途和恶意爬取。
一、前期准备(必看!环境搭建一步到位)
本次实战用到3个核心库,提前安装好,避免后续报错,新手直接复制命令执行即可。
1.1 所需库说明(新手不用记,知道用途就行)
-
requests:发送HTTP请求,获取股票网页数据(核心爬虫库,轻量易上手);
-
pandas:处理爬取到的股票数据(整理、去重、存储,简化数据操作);
-
mplfinance:绘制专业股票K线图(专门用于金融数据可视化,比matplotlib更简洁)。
1.2 库的安装(CMD/终端执行,复制粘贴即可)
# 批量安装所需库,版本兼容新手,无需额外配置
pip install requests pandas mplfinance --upgrade
安装报错解决:如果出现“pip不是内部命令”,大概率是Python环境变量未配置,新手可以直接在PyCharm的Terminal中执行上述命令(PyCharm会自动关联Python环境)。
二、核心步骤1:确定爬取目标与分析网页结构
新手爬取数据,第一步千万别急着写代码,先确定“爬哪里、爬什么”,再分析网页数据的加载方式——这是避免爬虫报错的关键!
2.1 爬取目标
本次选择「东方财富网」的股票实时行情页(公开数据,反爬难度低,适合新手),爬取内容:
-
股票代码、股票名称
-
实时价格、开盘价、收盘价(前一交易日)
-
涨跌额、涨幅(核心分析指标)
爬取地址(可直接复制到浏览器打开):https://quote.eastmoney.com/center/gridlist.html#hs_a_board
2.2 分析网页结构(新手必学!)
打开上述网页,按「F12」打开开发者工具(Chrome/Firefox浏览器都可以),步骤如下:
-
点击开发者工具左上角的「箭头」(选择元素),点击网页中的股票数据表格,会自动定位到网页源码中的表格位置;
-
观察源码可知,股票数据全部放在「table」标签中,每一行股票对应一个「tr」标签,每一个数据字段(如开盘价、涨幅)对应一个「td」标签;
-
关键结论:该网页数据是「静态加载」(刷新网页就能看到源码中的数据),无需处理AJAX异步加载,新手可直接爬取,难度大大降低!
提示:如果看不到表格源码,刷新一下网页即可;如果是动态加载(源码中找不到数据),本文末尾会补充解决方法,新手先专注静态加载实战。
三、核心步骤2:编写爬虫,爬取股票实时数据(手把手敲代码)
本次爬虫分3个小模块:发送请求→解析数据→保存数据,每个模块单独编写,方便新手调试(报错时能快速定位问题),完整代码附注释,直接复制就能运行。
3.1 模块1:发送请求,获取网页源码
核心作用:模拟浏览器访问网页,获取网页的HTML源码(后续从源码中提取股票数据),重点是添加请求头,避免被网站识别为爬虫。
import requests
# 1. 定义爬取地址(东方财富网A股实时行情页)
url = "https://quote.eastmoney.com/center/gridlist.html#hs_a_board"
# 2. 添加请求头,模拟浏览器访问(关键!避免被反爬)
headers = {
"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",
"Referer": "https://quote.eastmoney.com/", # 模拟从东方财富网首页跳转过来,更真实
"Accept-Language": "zh-CN,zh;q=0.9" # 模拟中文浏览器环境
}
# 3. 发送GET请求,获取网页源码
try:
response = requests.get(url=url, headers=headers, timeout=10)
response.encoding = "utf-8" # 设置编码,避免中文乱码
# 验证请求是否成功(状态码200表示成功)
if response.status_code == 200:
print("请求成功!已获取网页源码")
html = response.text # 提取网页源码,后续用于解析数据
else:
print(f"请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"请求报错,错误信息:{e}")
3.2 模块2:解析数据,提取核心字段
核心作用:从网页源码中,提取我们需要的股票数据(代码、名称、开盘价等),这里用「正则表达式」解析(新手易上手,无需额外学BeautifulSoup)。
补充:正则表达式匹配规则,已帮大家写好,新手不用深究,直接复用即可,重点看注释理解每一步的作用。
import re
import pandas as pd
# 定义一个列表,用于存储所有股票数据
stock_data = []
# 用正则表达式解析网页源码,提取股票核心数据
# 匹配规则:根据网页源码的结构编写,精准匹配每一行股票数据
pattern = re.compile(
r'.*?([0-9]{6}) .*?' # 股票代码
r'([^<]*) .*?' # 股票名称
r'([0-9]+.[0-9]+) .*?' # 实时价格
r'([0-9]+.[0-9]+) .*?' # 开盘价
r'([0-9]+.[0-9]+) .*?' # 收盘价(前一交易日)
r'([-+]?[0-9]+.[0-9]+) .*?' # 涨跌额
r'([-+]?[0-9]+.[0-9]+)% ', # 涨幅(带%)
re.S # 忽略换行符,确保能匹配到完整的一行股票数据
)
# 查找所有匹配的数据
matches = pattern.findall(html)
# 遍历匹配结果,整理数据(将每一只股票的数据存入列表)
for match in matches:
stock_code = match[0] # 股票代码
stock_name = match[1] # 股票名称
current_price = float(match[2]) # 实时价格(转换为浮点数,方便后续计算)
open_price = float(match[3]) # 开盘价
close_price = float(match[4]) # 收盘价(前一交易日)
change_amount = float(match[5]) # 涨跌额
change_rate = float(match[6]) # 涨幅(去掉%,转换为浮点数)
# 将单只股票数据存入字典,再添加到列表中
stock_dict = {
"股票代码": stock_code,
"股票名称": stock_name,
"实时价格": current_price,
"开盘价": open_price,
"收盘价(前一交易日)": close_price,
"涨跌额": change_amount,
"涨幅(%)": change_rate
}
stock_data.append(stock_dict)
# 验证解析结果(打印前5只股票数据,查看是否解析成功)
print("解析成功!前5只股票数据如下:")
print(pd.DataFrame(stock_data).head())
3.3 模块3:保存数据,方便后续分析
核心作用:将解析后的股票数据,保存为Excel文件(新手易查看、易复用),用pandas实现,一行代码就能搞定,无需手动创建Excel。
# 用pandas将列表中的数据转换为DataFrame(表格形式)
df = pd.DataFrame(stock_data)
# 保存为Excel文件,保存路径可自定义(这里保存在当前文件夹,文件名:股票实时数据.xlsx)
df.to_excel("股票实时数据.xlsx", index=False) # index=False:不保存行索引,更整洁
print("数据保存成功!已保存为:股票实时数据.xlsx")
print(f"共爬取到 {len(stock_data)} 只股票的数据")
3.4 完整爬虫代码(整合版,直接复制运行)
将上述3个模块整合,添加异常处理,避免报错终止程序,新手直接复制到PyCharm中,点击运行即可。
import requests
import re
import pandas as pd
def crawl_stock_data():
# 1. 发送请求,获取网页源码
url = "https://quote.eastmoney.com/center/gridlist.html#hs_a_board"
headers = {
"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",
"Referer": "https://quote.eastmoney.com/",
"Accept-Language": "zh-CN,zh;q=0.9"
}
try:
response = requests.get(url=url, headers=headers, timeout=10)
response.encoding = "utf-8"
if response.status_code != 200:
print(f"请求失败,状态码:{response.status_code}")
return None
html = response.text
except Exception as e:
print(f"请求报错:{e}")
return None
# 2. 解析数据,提取核心字段
stock_data = []
pattern = re.compile(
r'.*?([0-9]{6}) .*?'
r'([^<]*) .*?'
r'([0-9]+.[0-9]+) .*?'
r'([0-9]+.[0-9]+) .*?'
r'([0-9]+.[0-9]+) .*?'
r'([-+]?[0-9]+.[0-9]+) .*?'
r'([-+]?[0-9]+.[0-9]+)% ',
re.S
)
matches = pattern.findall(html)
for match in matches:
stock_dict = {
"股票代码": match[0],
"股票名称": match[1],
"实时价格": float(match[2]),
"开盘价": float(match[3]),
"收盘价(前一交易日)": float(match[4]),
"涨跌额": float(match[5]),
"涨幅(%)": float(match[6])
}
stock_data.append(stock_dict)
if not stock_data:
print("未解析到任何股票数据,请检查正则表达式匹配规则")
return None
# 3. 保存数据为Excel
df = pd.DataFrame(stock_data)
df.to_excel("股票实时数据.xlsx", index=False)
print(f"爬取成功!共获取 {len(stock_data)} 只股票数据,已保存为:股票实时数据.xlsx")
return df
# 执行爬虫函数,获取股票数据DataFrame(后续用于绘制K线图)
stock_df = crawl_stock_data()
爬虫运行结果说明
-
运行成功后,控制台会打印“请求成功”“爬取成功”的提示,以及前5只股票的数据;
-
在当前Python文件所在的文件夹中,会生成一个「股票实时数据.xlsx」文件,打开后就能看到所有爬取的股票数据,格式整洁,可直接编辑;
-
常见报错解决:如果未解析到数据,大概率是网页结构更新,正则表达式匹配规则失效,可重新按F12查看网页源码,调整正则表达式(新手可留言,我会补充最新匹配规则);如果保存Excel报错,重新安装pandas库即可。
四、核心步骤3:绘制K线图,分析股票走势(新手也能画)
爬取到数据后,重点是通过K线图分析股票走势——K线图是股票分析的核心工具,能直观展示开盘价、收盘价、涨跌情况。本次用mplfinance库,无需手动调整参数,一行代码就能绘制专业K线图。
4.1 补充:K线图绘制的前提(新手必看)
K线图需要「时间序列数据」(即某只股票连续多日的开盘价、收盘价、最高价、最低价),而我们上面爬取的是「实时行情数据」(单时间点的所有股票数据),因此需要补充一步:获取单只股票的历史数据(连续多日)。
下面补充代码:基于上面的爬虫,添加“获取单只股票历史数据”的函数,再绘制K线图(整合到完整代码中,直接运行)。
4.2 完整代码:获取单只股票历史数据+绘制K线图
import mplfinance as mpf
import datetime
def get_stock_history(stock_code, start_date, end_date):
"""
获取单只股票的历史数据(用于绘制K线图)
:param stock_code: 股票代码(如600000,浦发银行)
:param start_date: 开始日期(格式:YYYY-MM-DD,如2024-01-01)
:param end_date: 结束日期(格式:YYYY-MM-DD,如2024-12-31)
:return: 股票历史数据DataFrame
"""
# 东方财富网股票历史数据接口(公开接口,无需登录)
url = f"https://q.stock.sohu.com/hisHq?code=cn_{stock_code}&start={start_date}&end={end_date}&stat=1&order=D&period=d&callback=historySearchHandler&rt=jsonp&r=0.8837431436340332&0.6352749954223633"
headers = {
"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"
}
try:
response = requests.get(url=url, headers=headers, timeout=10)
response.encoding = "utf-8"
if response.status_code != 200:
print(f"获取历史数据失败,状态码:{response.status_code}")
return None
# 解析接口返回的数据(JSON格式,需要处理字符串,提取有效数据)
data_str = response.text.lstrip("historySearchHandler(").rstrip(")")
import json
data_json = json.loads(data_str)
# 提取历史数据,整理为DataFrame
history_data = []
for item in data_json[0]["hq"]:
date = item[0] # 日期
open_price = float(item[1]) # 开盘价
close_price = float(item[2]) # 收盘价
high_price = float(item[3]) # 最高价
low_price = float(item[4]) # 最低价
change_rate = float(item[8].strip("%")) # 涨幅
history_dict = {
"日期": date,
"开盘价": open_price,
"收盘价": close_price,
"最高价": high_price,
"最低价": low_price,
"涨幅(%)": change_rate
}
history_data.append(history_dict)
# 转换为DataFrame,调整日期格式(用于mplfinance绘制K线图)
df = pd.DataFrame(history_data)
df["日期"] = pd.to_datetime(df["日期"]) # 将日期转换为datetime格式
df.set_index("日期", inplace=True) # 将日期设为索引(mplfinance要求)
df = df.sort_index() # 按日期升序排列
print(f"成功获取 {stock_code} 股票 {start_date} 至 {end_date} 的历史数据,共 {len(df)} 条")
return df
except Exception as e:
print(f"获取历史数据报错:{e}")
return None
# 示例:获取「浦发银行(600000)」2024年1月1日至2024年12月31日的历史数据
stock_code = "600000" # 可替换为其他股票代码(如000001,平安银行)
start_date = "2024-01-01"
end_date = "2024-12-31"
history_df = get_stock_history(stock_code, start_date, end_date)
# 绘制K线图(专业美观,新手无需调整参数)
if history_df is not None:
# 设置K线图样式(默认样式即可,也可自定义颜色)
mpf_style = mpf.make_mpf_style(base_mpf_style="yahoo", rc={"font.size": 10})
# 绘制K线图,添加涨幅均线(MA5、MA10),更直观分析走势
mpf.plot(
history_df,
type="candle", # 图表类型:K线图(candle=蜡烛图,即K线图)
style=mpf_style, # 图表样式
title=f"{stock_code} 股票K线图({start_date} - {end_date})", # 图表标题
ylabel="价格(元)", # Y轴标签
ylabel_lower="涨幅(%)", # 下方Y轴标签
addplot=[
mpf.make_addplot(history_df["涨幅(%)"], panel=1, color="red", label="涨幅(%)") # 下方添加涨幅曲线
],
mav=(5, 10), # 添加5日、10日均线(用于分析短期走势)
volume=False, # 不显示成交量(新手可先关闭,简化图表)
show_nontrading=False, # 不显示非交易日
figratio=(12, 8), # 图表比例(宽12,高8,美观)
tight_layout=True # 紧凑布局,避免标签遮挡
)
K线图绘制结果说明
-
运行代码后,会自动弹出一个窗口,显示股票K线图,包含:
-
红色K线:收盘价 > 开盘价(上涨);
-
绿色K线:收盘价 < 开盘价(下跌);
-
黄色线:5日均线(短期走势参考);
-
紫色线:10日均线(短期走势参考);
-
下方红色曲线:每日涨幅(直观查看涨跌波动)。
-
自定义调整:新手可替换「stock_code」为其他股票代码(如000001平安银行、601318中国平安),调整「start_date」和「end_date」更换时间范围;
-
报错解决:如果弹出的K线图空白,大概率是日期格式错误,确保start_date和end_date的格式为“YYYY-MM-DD”;如果获取不到历史数据,更换股票代码即可。
五、新手实战拓展(可选,进阶提升)
学会基础爬取和K线图绘制后,新手可尝试以下拓展,提升实战能力:
5.1 拓展1:爬取多只股票的历史数据,批量绘制K线图
将股票代码存入列表,循环调用「get_stock_history」函数,批量获取多只股票的历史数据,批量绘制K线图(代码示例如下):
# 批量爬取多只股票的历史数据,批量绘制K线图
stock_codes = ["600000", "000001", "601318"] # 浦发银行、平安银行、中国平安
start_date = "2024-01-01"
end_date = "2024-12-31"
for code in stock_codes:
df = get_stock_history(code, start_date, end_date)
if df is not None:
mpf.plot(
df,
type="candle",
style=mpf.make_mpf_style(base_mpf_style="yahoo"),
title=f"{code} 股票K线图",
ylabel="价格(元)",
mav=(5, 10),
show_nontrading=False,
figratio=(12, 8)
)
5.2 拓展2:添加数据筛选功能,筛选涨幅大于5%的股票
利用pandas筛选爬取到的实时数据,筛选出涨幅大于5%的股票,保存为新的Excel文件,方便重点分析:
# 筛选涨幅大于5%的股票(基于之前爬取的实时数据stock_df)
if stock_df is not None:
high_growth_stock = stock_df[stock_df["涨幅(%)"] > 5]
if not high_growth_stock.empty:
high_growth_stock.to_excel("涨幅大于5%的股票.xlsx", index=False)
print(f"已筛选出 {len(high_growth_stock)} 只涨幅大于5%的股票,保存为:涨幅大于5%的股票.xlsx")
else:
print("暂无涨幅大于5%的股票")
5.3 拓展3:设置定时爬取,实时更新股票数据
利用「time」库,设置定时爬取(如每10分钟爬取一次实时数据),自动更新Excel文件,实现实时监控:
import time
# 定时爬取,每10分钟一次(600秒)
while True:
print(f"
{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}:开始定时爬取股票实时数据")
crawl_stock_data() # 调用爬虫函数
print("定时爬取完成,等待10分钟后再次爬取...")
time.sleep(600) # 等待600秒(10分钟)
六、常见问题汇总(新手必看,避坑指南)
- 问题1:请求成功,但解析不到股票数据?
解决:网页结构更新,正则表达式匹配规则失效,重新按F12查看网页源码,调整正则表达式的匹配内容。
- 问题2:绘制K线图时,报错“没有索引”?
解决:忘记将日期设为索引,确保调用「df.set_index(“日期”, inplace=True)」,且日期格式为datetime格式。
- 问题3:获取历史数据时,接口返回空?
解决:股票代码错误(A股代码为6位数字,如600开头、000开头),或时间范围过大,缩小时间范围即可。
-
问题4:中文乱码?
解决:设置response.encoding = “utf-8”,保存Excel时无需额外设置,pandas会自动处理中文编码。
-
问题5:被网站封禁IP?
解决:添加请求头,降低爬取频率(如定时爬取,每10分钟一次),避免高频请求,新手无需使用代理IP(公开股票数据反爬宽松)。
七、总结与学习建议
本次实战,我们完成了「股票实时数据爬取→数据保存→历史数据获取→K线图绘制」的全流程,核心重点:
-
爬虫部分:重点是模拟浏览器请求(添加请求头)、解析静态网页数据(正则表达式复用)、数据保存(pandas简化操作),新手无需追求复杂的解析库,先掌握基础正则表达式即可;
-
可视化部分:mplfinance库专门用于股票可视化,无需手动调整参数,重点是获取符合要求的历史数据(时间序列、包含开盘价/收盘价/最高价/最低价);
-
学习建议:新手先跟着代码敲一遍,确保能运行成功,再逐步修改参数(如更换股票代码、时间范围),尝试拓展功能(批量爬取、数据筛选),遇到报错不要慌,对照“常见问题汇总”排查,多调试几次就能掌握。
后续可尝试爬取基金数据、期货数据,或结合机器学习实现股票走势预测,逐步提升Python实战能力。
本文地址:https://www.yitenyun.com/5058.html
最新文章
热门文章








