Python爬虫实战:同花顺股票数据采集与量化分析
2026/9/14 22:58:18 网站建设 项目流程

1. 项目概述:Python爬取同花顺股票数据的技术实现

去年帮私募朋友做量化策略时,需要批量获取技术指标数据。传统手工导出效率太低,最终用Python实现了自动化采集方案。这个项目核心是通过爬虫技术从同花顺获取结构化股票数据,并提取MACD、KDJ等关键指标,为量化分析提供数据支持。

同花顺作为主流金融数据平台,其网页版包含丰富的技术指标数据,但缺乏批量导出功能。通过分析页面请求,我们发现其数据接口采用Ajax动态加载,需要模拟浏览器行为才能获取完整数据。本文将详解从环境搭建到指标提取的全流程实现,包含三个关键阶段:数据采集层(请求模拟与反爬绕过)、数据处理层(字段清洗与计算)、数据应用层(指标可视化与策略回测)。

提示:本项目仅用于技术学习,实际使用需遵守同花顺的用户协议。高频访问可能导致IP被封禁,建议控制请求频率在5秒/次以上。

2. 技术方案设计与环境准备

2.1 核心工具选型

经过对比测试,最终技术栈组合如下:

  • 请求库:Requests + selenium(主备双方案)
    • Requests处理静态接口(效率高)
    • selenium应对动态渲染(兼容性好)
  • 解析库:BeautifulSoup4 + pyquery
    • BS4用于HTML结构解析
    • pyquery处理类jQuery选择器
  • 数据处理:pandas + TA-Lib
    • pandas进行数据清洗
    • TA-Lib计算专业指标
  • 反爬方案:随机UserAgent + 代理IP池
# 基础依赖安装 pip install requests selenium beautifulsoup4 pyquery pandas pip install TA-Lib # 需先安装Windows版二进制包

2.2 同花顺接口分析

通过Chrome开发者工具(F12)分析网络请求,发现关键数据接口:

  1. 实时行情:https://data.10jqka.com.cn/
  2. 历史K线:https://d.10jqka.com.cn/v2/line/
  3. 指标数据:https://basic.10jqka.com.cn/

接口特点:

  • 需要携带RefererCookie鉴权
  • 分页参数采用pagesize控制
  • 返回数据为JSON格式(需处理Unicode编码)

3. 核心爬取流程实现

3.1 请求头模拟实战

成功请求的关键在于头部信息配置。通过实际抓包,我们整理出必须包含的字段:

headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": "https://stock.10jqka.com.cn/", "Cookie": "v=xxxxxx;", # 需登录后获取 "X-Requested-With": "XMLHttpRequest" }

实测发现同花顺对以下特征进行检测:

  • 缺少Referer直接返回403
  • 非常规UserAgent会触发验证码
  • 单IP高频访问会限流(建议配合代理)

3.2 数据解析与清洗

获取到的原始数据需要多层处理:

  1. HTML解编码:处理&#x开头的Unicode字符
  2. 字段提取:用CSS选择器定位关键元素
  3. 类型转换:字符串转数值/日期类型
def parse_stock_data(html): soup = BeautifulSoup(html, 'lxml') data = [] for tr in soup.select('tbody tr'): item = { 'code': tr.select_one('.stockCode').text, 'name': tr.select_one('.stockName').text, 'price': float(tr.select_one('.price').text), 'change': tr.select_one('.change').text } data.append(item) return pd.DataFrame(data)

3.3 技术指标计算方案

使用TA-Lib库计算专业指标时需注意参数设置:

指标类型函数名典型参数计算要点
MACDtalib.MACDfastperiod=12需输入close价格序列
KDJtalib.STOCH[9,3,3]需要high/low/close
RSItalib.RSItimeperiod=14单价格序列输入
BOLLtalib.BBANDS20返回上中下三条轨道线

踩坑记录:TA-Lib要求输入值为numpy数组,需提前用df['close'].values转换

4. 完整实现代码解析

4.1 主爬虫类设计

class ThsSpider: def __init__(self): self.session = requests.Session() self.session.headers.update(base_headers) def get_stock_list(self, page=1): url = f"https://data.10jqka.com.cn/financial/yjyg/order/desc/page/{page}/" try: resp = self.session.get(url, timeout=10) resp.raise_for_status() return self.parse_list(resp.text) except Exception as e: print(f"请求失败: {str(e)}") return None def parse_list(self, html): # 实现解析逻辑 pass

4.2 数据持久化方案

推荐两种存储方式:

  1. CSV文件(适合小型数据集)
    df.to_csv('stock_data.csv', index=False, encoding='utf_8_sig')
  2. MySQL数据库(推荐生产环境使用)
    from sqlalchemy import create_engine engine = create_engine('mysql://user:pass@host/db') df.to_sql('stock_data', engine, if_exists='append')

4.3 定时任务配置

使用APScheduler实现自动化采集:

from apscheduler.schedulers.blocking import BlockingScheduler sched = BlockingScheduler() @sched.scheduled_job('cron', hour=15, minute=30) # 收盘后运行 def daily_job(): spider = ThsSpider() spider.get_stock_list() sched.start()

5. 常见问题与优化方案

5.1 反爬应对策略

根据实测经验整理的反爬解决方案:

现象解决方案实现示例
返回验证码降低频率+更换UAheaders['User-Agent'] = random.choice(ua_list)
IP被封禁使用代理IP轮询proxies = {"https": "http://ip:port"}
数据加载不全改用selenium渲染driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
接口返回空数据检查Cookie有效期重新登录更新Cookie

5.2 性能优化技巧

  1. 异步请求加速:改用aiohttp实现并发
    async with aiohttp.ClientSession() as session: async with session.get(url) as resp: return await resp.text()
  2. 缓存复用机制:对基础数据本地缓存
  3. 增量采集策略:记录最后更新时间戳

5.3 数据质量校验

建议增加的校验规则:

def validate_data(df): # 检查空值率 if df.isnull().mean().max() > 0.3: raise ValueError("数据缺失严重") # 检查价格合理性 if (df['price'] <= 0).any(): raise ValueError("存在异常价格")

6. 技术指标应用实例

6.1 MACD策略信号生成

def generate_signals(df): df['macd'], df['signal'], _ = talib.MACD(df['close']) df['position'] = np.where(df['macd'] > df['signal'], 1, -1) return df

6.2 可视化分析

使用matplotlib绘制指标曲线:

plt.figure(figsize=(12,6)) plt.plot(df['date'], df['close'], label='Close') plt.plot(df['date'], df['upper'], 'r--', label='Upper Band') plt.legend() plt.show()

在项目落地过程中,发现同花顺的移动平均线计算方式与TA-Lib存在差异。经过比对,确认是同花顺使用了前复权价格计算,而我们的原始数据未复权。解决方案是在计算前先对价格序列进行复权处理,保证指标一致性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询