全国高铁列车时刻表数据获取方案
📋 问题分析
12306 数据获取难点
-
反爬虫严格:12306 有严格的反爬机制,包括:
- 验证码(滑块、点选)
- IP 频率限制
- 请求签名加密
- 需要登录态
-
数据量巨大:
- 全国高铁线路:5000+ 条
- 每日车次:10000+ 趟
- 车站:3000+ 个
-
数据动态更新:
- 铁路调图:每季度一次
- 临时加开/停运
- 时刻调整
🔧 可行方案
方案一:使用第三方 API 服务(推荐⭐⭐⭐⭐⭐)
优点:
- 数据稳定可靠
- 无需维护爬虫
- 实时更新
- 有免费额度
推荐服务商:
| 服务商 | API 名称 | 免费额度 | 价格 | 文档 |
|---|---|---|---|---|
| 聚合数据 | 火车票务查询 | 100 次/天 | ¥0.01/次 | https://www.juhe.cn/docs/api/id/18 |
| 阿里云市场 | 12306 车次查询 | 100 次/月 | ¥0.02/次 | https://market.aliyun.com/products/57126001/cmapi033233.html |
| 万维易源 | 火车时刻表 | 50 次/天 | ¥0.015/次 | https://www.showapi.com/apiGateway/view/185 |
| 天行数据 | 火车票查询 | 100 次/天 | 免费 | https://www.tianapi.com/apiview/163 |
示例代码:
import requests
# 聚合数据示例
def query_train_by_juhe(station_from, station_to, date):
url = "http://v.juhe.cn/train/s2s"
params = {
"from": station_from,
"to": station_to,
"date": date,
"key": "YOUR_API_KEY"
}
response = requests.get(url, params=params)
return response.json()
# 查询北京→上海 2026-03-15 的车次
result = query_train_by_juhe("北京", "上海", "2026-03-15")
print(result)
方案二:爬取公开数据源(⭐⭐⭐)
数据源:
- 高铁管家:http://www.tieyou.com
- 携程火车票:https://trains.ctrip.com
- 途牛火车票:http://huoche.tuniu.com
优点:
- 免费
- 数据较全
缺点:
- 需要维护爬虫
- 可能被封 IP
- 数据更新不及时
示例代码:
# 携程火车票爬虫示例
import requests
from bs4 import BeautifulSoup
def query_ctrip_train(from_station, to_station, date):
url = "https://trains.ctrip.com/TrainBooking/Search"
params = {
"from": from_station,
"to": to_station,
"date": date
}
headers = {
"User-Agent": "Mozilla/5.0",
"Referer": "https://trains.ctrip.com"
}
response = requests.get(url, params=params, headers=headers)
# 解析结果...
方案三:离线数据 + 定期更新(⭐⭐⭐⭐)
思路:
- 首次获取完整时刻表(约 10MB JSON)
- 存储到本地数据库
- 每周/每月更新一次
- 旅行规划时查询本地数据
数据来源:
- GitHub 开源项目(搜索"train schedule")
- 一次性爬取后缓存
- 购买商业数据
存储方案:
{
"trains": [
{
"train_no": "G1",
"from_station": "北京南",
"to_station": "上海虹桥",
"departure_time": "09:00",
"arrival_time": "13:28",
"duration": "4h28m",
"stops": [
{"station": "天津南", "time": "09:32"},
{"station": "济南西", "time": "10:28"},
{"station": "南京南", "time": "12:00"}
]
}
]
}
方案四:12306 官方接口(⭐⭐)
接口地址:
- 余票查询:
https://kyfw.12306.cn/otn/leftTicket/query - 车次查询:
https://kyfw.12306.cn/otn/cxycx/query
缺点:
- 需要 Cookie 和验证码
- 反爬严格
- 不建议使用
📊 推荐方案
最佳实践(综合方案)
短期方案(立即使用):
- 申请聚合数据或天行数据免费 API key
- 封装查询函数
- 用于旅行规划时的实时查询
长期方案(数据积累):
- 使用 API 查询热门线路(北京、上海、西安等)
- 缓存到本地 JSON/SQLite
- 建立本地时刻表数据库
- 定期(每周)更新热门线路
混合方案:
- 优先查本地缓存
- 缓存没有的调用 API
- 新查询结果写入缓存
🔑 API Key 申请指南
天行数据(推荐,完全免费)
- 访问:https://www.tianapi.com
- 注册账号
- 进入控制台 → 我的接口 → 申请开通"火车票务"
- 获取 API Key
- 免费额度:100 次/天
聚合数据
- 访问:https://www.juhe.cn
- 注册账号
- 搜索"火车票务"
- 申请免费试用
- 免费额度:100 次/天
📝 下一步行动
- 申请 API Key(推荐天行数据)
-
创建查询脚本:
scripts/train_schedule/query.py - 测试查询:北京→西安、北京→上海等热门线路
- 建立缓存机制:SQLite/JSON
- 集成到旅行规划流程
💡 使用建议
旅行规划时的查询策略
-
出发前查询:
- 规划时查询大致车次(日期可调整)
- 记录推荐车次(如 G655 北京西 07:38→西安北 12:38)
-
用户确认:
- 告知用户车次信息
- 建议用户自行在 12306 核实并购票
-
标注说明:
| 车次 | 区间 | 出发 | 到达 | 历时 | 票价 | |------|------|------|------|------|------| | G655 | 北京西→西安北 | 07:38 | 12:38 | 5h | ¥515 | > ⚠️ 具体车次请以 12306 查询为准,建议提前 7-15 天购票
创建日期:2026-03-14 维护者:Travel Agent