新增功能: - 5个专业数据抓取器(公司信息、板块、财务、资金流、龙虎榜) - 一键执行脚本 run_all_fetchers.sh(完整/测试/自定义三种模式) - 扩展数据库Schema(11张新表) - 数据源迁移至免费API(东方财富、新浪、腾讯) 数据能力: - 公司基础信息:5,295只A股 - 板块数据:~400个板块 + 20万成分股关系 - 财务报表:利润表+资产负债表(最近4季) - 资金流:主力资金、大单、中单、小单(700天) - 龙虎榜:上榜记录+营业部明细(2年) - 总数据量:~395万条记录,3-5GB存储 技术亮点: - 断点续传支持 - UPSERT策略避免重复 - API限流控制 - 实时进度显示 - 错误容错机制 - 完整日志记录 文档更新: - README添加"全量数据抓取"章节 - 60+页技术方案文档 - 完整的使用指南和维护文档 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
18 KiB
18 KiB
A股全量历史数据抓取指南
📖 概述
本系统提供全自动、可断点续传、支持增量更新的A股历史数据抓取功能,可抓取所有A股股票过去10年的完整历史数据。
核心特性
- ✅ 全量抓取: 支持抓取全部5000+只A股股票
- ✅ 断点续传: 中途失败可以继续,不会重复抓取
- ✅ 增量更新: 自动检测缺失数据,只抓取新增部分
- ✅ 进度跟踪: 实时显示抓取进度,支持查看统计信息
- ✅ 容错机制: 自动重试失败的股票
- ✅ 速率限制: 避免请求过快被封禁
- ✅ 数据完整性: 自动去重,确保数据质量
🚀 快速开始
1. 首次运行(抓取所有股票)
cd backend
source .venv/bin/activate
# 抓取所有A股股票过去10年数据
python fetch_full_historical_data.py
预期结果:
- 自动从新浪财经获取5000+只A股股票列表
- 开始批量抓取每只股票的历史数据
- 实时显示进度和统计信息
- 数据自动存储到PostgreSQL数据库
预计时间:
- 5000只股票 × 0.5秒/只 ≈ 42分钟(实际时间取决于网络速度)
2. 增量更新(只抓取新数据)
当您已经抓取过一次数据,现在想更新到最新数据时:
python fetch_full_historical_data.py --mode incremental
工作原理:
- 自动检查数据库中每只股票的最后交易日期
- 只抓取该日期之后的新数据
- 大幅减少抓取时间(通常只需几分钟)
推荐: 设置定时任务每天运行增量更新
# 添加到 crontab (每天收盘后18:00更新)
0 18 * * * cd /path/to/backend && source .venv/bin/activate && python fetch_full_historical_data.py --mode incremental
3. 重试失败的股票
如果某些股票抓取失败(网络问题、数据源问题等),可以单独重试:
python fetch_full_historical_data.py --mode retry
4. 指定股票列表
只抓取特定股票:
# 抓取贵州茅台、平安银行、浦发银行
python fetch_full_historical_data.py --symbols 600519,000001,600000
5. 自定义日期范围
# 只抓取最近5年数据
python fetch_full_historical_data.py --start-date 2020-01-01 --end-date 2025-12-31
# 抓取过去20年数据
python fetch_full_historical_data.py --start-date 2005-01-01
📊 进度管理
查看整体进度
python manage_fetch_progress.py --action status
输出示例:
================================================================================
📊 抓取进度统计
================================================================================
总股票数: 5,234
✅ 已完成: 4,890 (93.4%)
⏳ 待处理: 200
❌ 失败: 144
🔄 进行中: 0
📈 总数据量: 12,456,789 条
📊 平均数据/股: 2,546 条
================================================================================
🏆 数据量最多的10只股票:
----------------------------------------------------------------------------
代码 名称 数据量 开始日期 结束日期
----------------------------------------------------------------------------
600000 浦发银行 2,689条 2015-12-21 2025-12-19
000001 平安银行 2,678条 2015-12-21 2025-12-19
...
查看失败的股票
python manage_fetch_progress.py --action failed
输出示例:
================================================================================
❌ 失败的股票列表 (共 144 只)
================================================================================
[1] 688001 (华兴源创)
重试次数: 3
失败时间: 2025-12-21 14:30:15
错误信息: 无法获取K线数据
[2] 300750 (宁德时代)
重试次数: 2
失败时间: 2025-12-21 14:28:42
错误信息: Connection timeout
重置失败的股票
允许重新抓取失败的股票:
python manage_fetch_progress.py --action reset-failed
然后运行:
python fetch_full_historical_data.py --mode retry
导出进度报告
python manage_fetch_progress.py --action export --output my_report.txt
生成详细的进度报告文件,包括:
- 总体统计
- 已完成股票列表
- 失败股票详情
- 数据覆盖率分析
数据质量检查
python manage_fetch_progress.py --action quality
自动检测:
- 数据可能过时的股票(超过7天未更新)
- 数据量异常偏低的股票
- 数据完整性问题
🏗️ 系统架构
数据流图
┌─────────────────────────────────────────────────────────────┐
│ 1. 获取股票列表 │
│ ┌────────────┐ ┌────────────┐ │
│ │ 新浪财经 │ ──OR──> │ 东方财富 │ │
│ │ 5000+股票 │ │ (备用) │ │
│ └──────┬─────┘ └────────────┘ │
└─────────┼───────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 进度跟踪表 (fetch_progress) │
│ ┌──────────────────────────────────────────────┐ │
│ │ symbol │ status │ total_records │ dates │ │
│ ├──────────────────────────────────────────────┤ │
│ │ 600000 │ completed │ 2,689 │ 2015~25 │ │
│ │ 000001 │ pending │ 0 │ NULL │ │
│ │ 600519 │ failed │ 0 │ NULL │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 批量抓取 (DataFetcherV2) │
│ - 每只股票: 检查进度 → 抓取数据 → 存储 → 更新进度 │
│ - 自动重试失败股票 │
│ - 速率限制: 0.5秒/股票 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 数据存储 (PostgreSQL) │
│ ┌─────────────┐ ┌────────────────────┐ │
│ │ stocks │ │ daily_quotes │ │
│ │ (5,234) │ │ (12,456,789) │ │
│ └─────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
核心表结构
fetch_progress (进度跟踪表)
CREATE TABLE fetch_progress (
symbol VARCHAR(20) PRIMARY KEY, -- 股票代码
name VARCHAR(100), -- 股票名称
status VARCHAR(20), -- pending, in_progress, completed, failed
start_date DATE, -- 数据开始日期
end_date DATE, -- 数据结束日期
last_fetch_date DATE, -- 最后抓取日期
total_records INT, -- 总数据量
error_message TEXT, -- 错误信息
retry_count INT, -- 重试次数
created_at TIMESTAMP, -- 创建时间
updated_at TIMESTAMP -- 更新时间
);
状态说明:
pending: 待抓取in_progress: 正在抓取completed: 已完成failed: 失败
💡 最佳实践
1. 首次运行策略
推荐分阶段运行,避免一次性抓取全部股票:
# 阶段1: 先抓取1000只股票测试
python fetch_full_historical_data.py --mode full
# 观察进度,如果一切正常,继续
python manage_fetch_progress.py --action status
# 阶段2: 继续抓取剩余股票
python fetch_full_historical_data.py --mode full
2. 日常维护策略
每天自动增量更新:
# 方法1: crontab定时任务
0 18 * * * cd /path/to/backend && source .venv/bin/activate && python fetch_full_historical_data.py --mode incremental >> /var/log/stock_fetch.log 2>&1
# 方法2: systemd timer
# 创建 /etc/systemd/system/stock-fetch.service 和 stock-fetch.timer
每周检查数据质量:
# 检查是否有失败的股票
python manage_fetch_progress.py --action failed
# 重试失败的股票
python fetch_full_historical_data.py --mode retry
# 查看数据质量
python manage_fetch_progress.py --action quality
3. 错误处理
常见错误及解决方法:
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
Connection timeout |
网络超时 | 重试或检查网络 |
无法获取K线数据 |
股票已退市或数据源无此股票 | 忽略或手动排查 |
Database connection failed |
数据库连接失败 | 检查数据库服务 |
Rate limit exceeded |
请求过快 | 增加sleep时间 |
批量重试失败股票:
# 1. 重置失败状态
python manage_fetch_progress.py --action reset-failed
# 2. 重新抓取
python fetch_full_historical_data.py --mode retry
# 3. 查看结果
python manage_fetch_progress.py --action status
4. 性能优化
调整并发数 (需修改代码):
# fetch_full_historical_data.py
# 修改 sleep 时间
await asyncio.sleep(0.5) # 默认0.5秒,可调整为0.2~1.0秒
数据库优化:
-- 创建索引加速查询
CREATE INDEX idx_daily_quotes_symbol_date ON daily_quotes(symbol, trade_date);
CREATE INDEX idx_fetch_progress_status ON fetch_progress(status);
-- 定期VACUUM
VACUUM ANALYZE daily_quotes;
VACUUM ANALYZE fetch_progress;
📈 数据统计示例
完整抓取后的数据规模
假设抓取5000只股票,每只平均2500条数据(约10年):
总股票数: 5,000 只
总数据量: 12,500,000 条
数据库大小: 约 2-3 GB
抓取时间: 约 40-60 分钟(首次)
增量更新: 约 5-10 分钟(每天)
数据覆盖率
-- 查看各年份数据覆盖情况
SELECT
DATE_PART('year', trade_date) as year,
COUNT(DISTINCT symbol) as symbols,
COUNT(*) as records
FROM daily_quotes
GROUP BY year
ORDER BY year DESC;
典型输出:
year | symbols | records
------+---------+----------
2025 | 5234 | 950,000
2024 | 5180 | 1,260,000
2023 | 5120 | 1,240,000
2022 | 5050 | 1,220,000
...
🔧 故障排除
问题1: 进度表未创建
现象: relation "fetch_progress" does not exist
解决:
# 运行一次脚本会自动创建
python fetch_full_historical_data.py --symbols 600000
问题2: 大量股票失败
现象: failed 状态股票超过10%
可能原因:
- 网络不稳定
- 数据源被限流
- 股票已退市
解决:
# 查看失败详情
python manage_fetch_progress.py --action failed
# 重置并重试
python manage_fetch_progress.py --action reset-failed
python fetch_full_historical_data.py --mode retry
问题3: 数据重复
现象: 同一天的数据出现多次
解决: 数据库有唯一约束,自动去重
-- 手动清理重复数据(如果需要)
DELETE FROM daily_quotes a USING (
SELECT MIN(id) as id, symbol, trade_date
FROM daily_quotes
GROUP BY symbol, trade_date HAVING COUNT(*) > 1
) b
WHERE a.symbol = b.symbol AND a.trade_date = b.trade_date AND a.id <> b.id;
问题4: 内存占用过高
解决:
# 分批抓取,每次限制股票数量
# 修改代码中的批量大小或手动分批执行
python fetch_full_historical_data.py --symbols $(python -c "import random; print(','.join([f'{x:06d}' for x in random.sample(range(600000, 603000), 100)]))")
📝 脚本参数说明
fetch_full_historical_data.py
python fetch_full_historical_data.py [OPTIONS]
选项:
--mode {full,incremental,retry}
运行模式(默认: full)
- full: 抓取所有待处理股票
- incremental: 只抓取需要更新的股票
- retry: 只重试失败的股票
--symbols SYMBOLS
指定股票代码,逗号分隔
示例: --symbols 600000,000001,600519
--start-date YYYY-MM-DD
开始日期(默认: 10年前)
--end-date YYYY-MM-DD
结束日期(默认: 今天)
示例:
# 抓取全部股票
python fetch_full_historical_data.py
# 增量更新
python fetch_full_historical_data.py --mode incremental
# 抓取指定股票
python fetch_full_historical_data.py --symbols 600000,000001
# 自定义日期范围
python fetch_full_historical_data.py --start-date 2020-01-01
manage_fetch_progress.py
python manage_fetch_progress.py --action ACTION [OPTIONS]
操作:
status 显示整体进度统计
failed 显示失败的股票列表
reset-failed 重置失败股票状态
export 导出进度报告
clear-all 清理所有进度数据
quality 数据质量检查
选项:
--output FILE
导出报告的文件名(仅用于 export 操作)
默认: progress_report.txt
示例:
# 查看进度
python manage_fetch_progress.py --action status
# 导出报告
python manage_fetch_progress.py --action export --output report_2025.txt
🎯 完整工作流程示例
场景1: 首次建立数据库
# Step 1: 初始化数据库(如果未初始化)
psql -h localhost -U stock_user -d stock_db -f database/schema_v2.sql
# Step 2: 开始全量抓取
python fetch_full_historical_data.py
# Step 3: 观察进度(可在另一个终端窗口)
watch -n 10 'python manage_fetch_progress.py --action status'
# Step 4: 等待完成后检查数据质量
python manage_fetch_progress.py --action quality
# Step 5: 如有失败,重试
python fetch_full_historical_data.py --mode retry
# Step 6: 导出报告
python manage_fetch_progress.py --action export --output initial_fetch_report.txt
场景2: 每日增量更新
# Step 1: 每天18:00运行增量更新
python fetch_full_historical_data.py --mode incremental
# Step 2: 查看更新情况
python manage_fetch_progress.py --action status
# Step 3: 如有失败,立即重试
python fetch_full_historical_data.py --mode retry
场景3: 部分股票数据缺失
# Step 1: 查看数据质量
python manage_fetch_progress.py --action quality
# Step 2: 针对缺失数据的股票重新抓取
python fetch_full_historical_data.py --symbols 600000,000001,600519
# Step 3: 验证数据
psql -h localhost -U stock_user -d stock_db -c "
SELECT symbol, COUNT(*), MIN(trade_date), MAX(trade_date)
FROM daily_quotes
WHERE symbol IN ('600000', '000001', '600519')
GROUP BY symbol;
"
📚 相关文档
❓ 常见问题
Q: 抓取5000只股票需要多久?
A: 约40-60分钟(取决于网络速度),每只股票约0.5秒。
Q: 如何停止正在运行的抓取?
A: 直接 Ctrl+C 终止,下次运行会自动断点续传。
Q: 抓取失败率高怎么办?
A:
- 检查网络连接
- 增加 sleep 时间(降低请求频率)
- 查看失败详情:
python manage_fetch_progress.py --action failed
Q: 如何清空所有数据重新开始?
A:
# 清空进度表
python manage_fetch_progress.py --action clear-all
# 清空数据表(可选)
psql -h localhost -U stock_user -d stock_db -c "TRUNCATE daily_quotes, stocks CASCADE;"
# 重新抓取
python fetch_full_historical_data.py
Q: 支持港股、美股吗?
A: 当前版本仅支持A股,未来版本会扩展。
最后更新: 2025-12-21 版本: V2.0 维护者: Claude Code AI Assistant