全国高铁列车时刻表数据获取方案

📋 问题分析

12306 数据获取难点

  1. 反爬虫严格:12306 有严格的反爬机制,包括:
    • 验证码(滑块、点选)
    • IP 频率限制
    • 请求签名加密
    • 需要登录态
  2. 数据量巨大
    • 全国高铁线路:5000+ 条
    • 每日车次:10000+ 趟
    • 车站:3000+ 个
  3. 数据动态更新
    • 铁路调图:每季度一次
    • 临时加开/停运
    • 时刻调整

🔧 可行方案

方案一:使用第三方 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)

方案二:爬取公开数据源(⭐⭐⭐)

数据源

  1. 高铁管家:http://www.tieyou.com
  2. 携程火车票:https://trains.ctrip.com
  3. 途牛火车票: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)
    # 解析结果...

方案三:离线数据 + 定期更新(⭐⭐⭐⭐)

思路

  1. 首次获取完整时刻表(约 10MB JSON)
  2. 存储到本地数据库
  3. 每周/每月更新一次
  4. 旅行规划时查询本地数据

数据来源

  • 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 和验证码
  • 反爬严格
  • 不建议使用

📊 推荐方案

最佳实践(综合方案)

短期方案(立即使用)

  1. 申请聚合数据天行数据免费 API key
  2. 封装查询函数
  3. 用于旅行规划时的实时查询

长期方案(数据积累)

  1. 使用 API 查询热门线路(北京、上海、西安等)
  2. 缓存到本地 JSON/SQLite
  3. 建立本地时刻表数据库
  4. 定期(每周)更新热门线路

混合方案

  • 优先查本地缓存
  • 缓存没有的调用 API
  • 新查询结果写入缓存

🔑 API Key 申请指南

天行数据(推荐,完全免费)

  1. 访问:https://www.tianapi.com
  2. 注册账号
  3. 进入控制台 → 我的接口 → 申请开通"火车票务"
  4. 获取 API Key
  5. 免费额度:100 次/天

聚合数据

  1. 访问:https://www.juhe.cn
  2. 注册账号
  3. 搜索"火车票务"
  4. 申请免费试用
  5. 免费额度:100 次/天

📝 下一步行动

  1. 申请 API Key(推荐天行数据)
  2. 创建查询脚本scripts/train_schedule/query.py
  3. 测试查询:北京→西安、北京→上海等热门线路
  4. 建立缓存机制:SQLite/JSON
  5. 集成到旅行规划流程

💡 使用建议

旅行规划时的查询策略

  1. 出发前查询
    • 规划时查询大致车次(日期可调整)
    • 记录推荐车次(如 G655 北京西 07:38→西安北 12:38)
  2. 用户确认
    • 告知用户车次信息
    • 建议用户自行在 12306 核实并购票
  3. 标注说明
    | 车次 | 区间 | 出发 | 到达 | 历时 | 票价 |
    |------|------|------|------|------|------|
    | G655 | 北京西→西安北 | 07:38 | 12:38 | 5h | ¥515 |
    
    > ⚠️ 具体车次请以 12306 查询为准,建议提前 7-15 天购票

创建日期:2026-03-14 维护者:Travel Agent