news 2026/7/17 8:39:24

Python爬虫实战:东方财富网股票数据抓取与MySQL存储

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python爬虫实战:东方财富网股票数据抓取与MySQL存储

1. 项目概述:爬取东方财富网股票数据并存储到MySQL

最近在做一个金融数据分析的小项目,需要获取A股市场的实时行情数据。东方财富网作为国内领先的财经门户,其股票数据页面结构清晰、更新及时,非常适合作为数据源。本文将分享如何用Python爬虫抓取东方财富网的个股数据,并通过PyMySQL库将清洗后的数据存入MySQL数据库的全过程。

这个方案特别适合以下场景:

  • 需要建立本地股票数据库进行量化分析
  • 想要定期采集特定股票的历史行情
  • 需要将不同来源的金融数据集中存储管理

提示:实际操作前请务必阅读东方财富网的robots.txt文件,控制爬取频率,建议设置2秒以上的请求间隔

2. 环境准备与工具选型

2.1 基础环境配置

首先需要准备以下环境:

  • Python 3.7+(推荐3.9版本)
  • MySQL 5.7+(社区版即可)
  • 开发工具:VS Code或PyCharm

关键Python库安装:

pip install requests beautifulsoup4 pymysql pandas

2.2 技术栈选择考量

选择Requests+BeautifulSoup组合而非Scrapy的原因:

  1. 东方财富网页面结构相对简单,不需要复杂的爬虫框架
  2. 项目数据量不大(单次抓取约几十只股票)
  3. 更轻量级,适合新手快速上手

选择MySQL存储的三大优势:

  1. 结构化存储便于后续的SQL查询分析
  2. 与Python生态集成良好(PyMySQL库)
  3. 支持事务,确保数据完整性

3. 网页分析与数据抓取

3.1 东方财富网页面结构解析

以贵州茅台(600519)的个股页面为例:

http://quote.eastmoney.com/sh600519.html

关键数据位置:

  • 当前价:class="price"的div
  • 涨跌幅:class="change"的span
  • 成交量:id="volume"的span
  • 市盈率:class="pe"的td

3.2 Python爬虫实现代码

import requests from bs4 import BeautifulSoup import time def get_stock_data(stock_code): url = f"http://quote.eastmoney.com/{'sh' if stock_code.startswith('6') else 'sz'}{stock_code}.html" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } try: response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') data = { 'code': stock_code, 'price': soup.find('div', class_='price').get_text(), 'change': soup.find('span', class_='change').get_text(), 'volume': soup.find('span', id='volume').get_text(), 'pe': soup.find('td', class_='pe').get_text(), 'timestamp': int(time.time()) } return data except Exception as e: print(f"获取{stock_code}数据失败:{str(e)}") return None

重要提醒:务必设置合理的请求间隔,建议使用time.sleep(2)控制爬取频率

4. MySQL数据库设计与存储实现

4.1 数据库表结构设计

创建stock_data表:

CREATE TABLE `stock_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, `stock_code` varchar(10) NOT NULL, `price` decimal(10,2) DEFAULT NULL, `change_percent` decimal(10,2) DEFAULT NULL, `volume` bigint(20) DEFAULT NULL, `pe_ratio` decimal(10,2) DEFAULT NULL, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_code` (`stock_code`), KEY `idx_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

4.2 Python连接MySQL的完整示例

import pymysql def save_to_mysql(data): connection = pymysql.connect( host='localhost', user='your_username', password='your_password', database='stock_db', charset='utf8mb4' ) try: with connection.cursor() as cursor: sql = """INSERT INTO stock_data (stock_code, price, change_percent, volume, pe_ratio) VALUES (%s, %s, %s, %s, %s)""" cursor.execute(sql, ( data['code'], float(data['price']), float(data['change'].strip('%')), int(data['volume']), float(data['pe']) )) connection.commit() finally: connection.close()

5. 完整工作流与优化方案

5.1 主程序逻辑整合

def main(): stock_list = ['600519', '000858', '601318'] # 茅台、五粮液、平安 for code in stock_list: data = get_stock_data(code) if data: save_to_mysql(data) time.sleep(3) # 严格遵守爬虫礼仪 if __name__ == '__main__': main()

5.2 性能优化建议

  1. 使用连接池管理数据库连接
  2. 实现异常重试机制(最多3次)
  3. 添加日志记录功能
  4. 考虑使用多线程加速(但要控制总请求频率)

6. 常见问题与解决方案

6.1 数据抓取失败排查

问题现象可能原因解决方案
返回403错误IP被限制1. 检查User-Agent 2. 增加延迟 3. 使用代理IP
数据为空页面改版1. 更新CSS选择器 2. 检查JavaScript渲染
连接超时网络问题1. 增加超时时间 2. 添加重试逻辑

6.2 MySQL存储异常处理

数据库写入时的三个关键检查点:

  1. 字段类型匹配(特别是字符串转数字)
  2. 唯一键冲突处理
  3. 事务回滚机制

改进后的存储函数示例:

def safe_save_to_mysql(data): try: # 转换数据类型 data['price'] = float(data['price']) data['change'] = float(data['change'].strip('%')) data['volume'] = int(data['volume'].replace(',', '')) data['pe'] = float(data['pe']) if data['pe'] != '-' else None save_to_mysql(data) except ValueError as e: print(f"数据格式错误:{e}") except pymysql.err.IntegrityError: print("重复数据,跳过") except Exception as e: print(f"数据库错误:{e}")

7. 项目扩展方向

7.1 定时任务实现

使用APScheduler实现定时采集:

from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() @scheduler.scheduled_job('cron', hour='9-15', minute='*/5') def scheduled_job(): main() scheduler.start()

7.2 数据可视化分析

结合Pandas和Matplotlib:

import matplotlib.pyplot as plt def analyze_data(): connection = pymysql.connect(...) df = pd.read_sql("SELECT * FROM stock_data WHERE create_time > DATE_SUB(NOW(), INTERVAL 7 DAY)", connection) plt.figure(figsize=(12,6)) for code, group in df.groupby('stock_code'): plt.plot(group['create_time'], group['price'], label=code) plt.legend() plt.show()

在实际项目中,我通常会设置凌晨2-4点进行历史数据补全,避免交易日的高峰时段。对于高频数据需求,建议考虑使用东方财富的API服务(如有),这比爬虫更稳定可靠。另外,MySQL表设计时预留了20%的额外字段,方便后续添加技术指标等衍生数据。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 8:38:02

Scikit-learn机器学习实战:从数据预处理到模型部署

1. SciPyCon 2018 sklearn教程背景解析 SciPyCon作为Python科学计算领域最具影响力的年度会议之一,2018年的sklearn教程由Scikit-learn核心开发团队亲自操刀设计。这个教程之所以成为经典,在于它系统性地覆盖了机器学习从数据预处理到模型部署的全流程&a…

作者头像 李华
网站建设 2026/7/17 8:36:44

CANN/asc-devkit SinCos缓冲区计算

GetSinCosTmpBufferFactorSize 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: h…

作者头像 李华
网站建设 2026/7/17 8:34:55

免U盘安装Windows双系统:原理与实战指南

1. 为什么选择无U盘/PE的Windows双系统方案传统双系统安装通常需要准备U盘启动盘或PE系统,这对很多用户来说存在几个实际痛点:首先,优质U盘并非人人常备,临时购买可能遇到扩容盘等质量问题;其次,制作启动盘…

作者头像 李华
网站建设 2026/7/17 8:34:25

CANN/asc-devkit Xor接口文档

Xor 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/cann/a…

作者头像 李华
网站建设 2026/7/17 8:32:55

CANN/Ascend C Gelu激活函数接口文档

Gelu 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/cann/…

作者头像 李华
网站建设 2026/7/17 8:32:48

电源设计中驱动电路的核心作用与设计要点

1. 驱动电路在电源设计中的核心地位 第一次接触电源设计时,我犯了个典型错误——把所有注意力都放在主功率拓扑上,结果样机调试时MOSFET频繁炸管。直到 mentor 指着驱动波形说"问题出在这里",我才真正理解:驱动电路就像…

作者头像 李华