前言:对于刚入门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源码(后续从源码中提取股票数据),重点是添加请求头,避免被网站识别为爬虫。
importrequests# 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表示成功)ifresponse.status_code==200:print("请求成功!已获取网页源码")html=response.text# 提取网页源码,后续用于解析数据else:print(f"请求失败,状态码:{response.status_code}")exceptExceptionase:print(f"请求报错,错误信息:{e}")3.2 模块2:解析数据,提取核心字段
核心作用:从网页源码中,提取我们需要的股票数据(代码、名称、开盘价等),这里用「正则表达式」解析(新手易上手,无需额外学BeautifulSoup)。
补充:正则表达式匹配规则,已帮大家写好,新手不用深究,直接复用即可,重点看注释理解每一步的作用。
importreimportpandasaspd# 定义一个列表,用于存储所有股票数据stock_data=[]# 用正则表达式解析网页源码,提取股票核心数据# 匹配规则:根据网页源码的结构编写,精准匹配每一行股票数据pattern=re.compile(r'<tr class="[^"]*">.*?<td><a href="[^"]*" target="_blank">([0-9]{6})</a></td>.*?'# 股票代码r'<td><a href="[^"]*" target="_blank" class="[^"]*">([^<]*)</a></td>.*?'# 股票名称r'<td class="[^"]*">([0-9]+\.[0-9]+)</td>.*?'# 实时价格r'<td class="[^"]*">([0-9]+\.[0-9]+)</td>.*?'# 开盘价r'<td class="[^"]*">([0-9]+\.[0-9]+)</td>.*?'# 收盘价(前一交易日)r'<td class="[^"]*">([-+]?[0-9]+\.[0-9]+)</td>.*?'# 涨跌额r'<td class="[^"]*">([-+]?[0-9]+\.[0-9]+)%</td>',# 涨幅(带%)re.S# 忽略换行符,确保能匹配到完整的一行股票数据)# 查找所有匹配的数据matches=pattern.findall(html)# 遍历匹配结果,整理数据(将每一只股票的数据存入列表)formatchinmatches: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中,点击运行即可。
importrequestsimportreimportpandasaspddefcrawl_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"ifresponse.status_code!=200:print(f"请求失败,状态码:{response.status_code}")returnNonehtml=response.textexceptExceptionase:print(f"请求报错:{e}")returnNone# 2. 解析数据,提取核心字段stock_data=[]pattern=re.compile(r'<tr class="[^"]*">.*?<td><a href="[^"]*" target="_blank">([0-9]{6})</a></td>.*?'r'<td><a href="[^"]*" target="_blank" class="[^"]*">([^<]*)</a></td>.*?'r'<td class="[^"]*">([0-9]+\.[0-9]+)</td>.*?'r'<td class="[^"]*">([0-9]+\.[0-9]+)</td>.*?'r'<td class="[^"]*">([0-9]+\.[0-9]+)</td>.*?'r'<td class="[^"]*">([-+]?[0-9]+\.[0-9]+)</td>.*?'r'<td class="[^"]*">([-+]?[0-9]+\.[0-9]+)%</td>',re.S)matches=pattern.findall(html)formatchinmatches: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)ifnotstock_data:print("未解析到任何股票数据,请检查正则表达式匹配规则")returnNone# 3. 保存数据为Exceldf=pd.DataFrame(stock_data)df.to_excel("股票实时数据.xlsx",index=False)print(f"爬取成功!共获取{len(stock_data)}只股票数据,已保存为:股票实时数据.xlsx")returndf# 执行爬虫函数,获取股票数据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线图
importmplfinanceasmpfimportdatetimedefget_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"ifresponse.status_code!=200:print(f"获取历史数据失败,状态码:{response.status_code}")returnNone# 解析接口返回的数据(JSON格式,需要处理字符串,提取有效数据)data_str=response.text.lstrip("historySearchHandler(").rstrip(")")importjson data_json=json.loads(data_str)# 提取历史数据,整理为DataFramehistory_data=[]foritemindata_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)}条")returndfexceptExceptionase:print(f"获取历史数据报错:{e}")returnNone# 示例:获取「浦发银行(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线图(专业美观,新手无需调整参数)ifhistory_dfisnotNone:# 设置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"forcodeinstock_codes:df=get_stock_history(code,start_date,end_date)ifdfisnotNone: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)ifstock_dfisnotNone:high_growth_stock=stock_df[stock_df["涨幅(%)"]>5]ifnothigh_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文件,实现实时监控:
importtime# 定时爬取,每10分钟一次(600秒)whileTrue:print(f"\n{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实战能力。