解析 12306 通知邮件导出的 txt 文件,生成结构化 JSON 数据和可视化 HTML 报表。
- 自动解析购票、退票、改签、候补兑现等多种票务事件
- 生成单文件 HTML 报表,支持离线查看
- 生成单文件 离线地图(站点/区间连线/热力/时间轴),支持离线查看
- 多维度筛选:年份、月份、时间范围、车次、车站、价格、席别、状态、同行范围
- 丰富统计:TOP10 车站/车次/区间、车次类型比例、席别分布、时间趋势
- 分文件导出:为每个来源 txt 单独生成一份数据,方便分别统计
Python 3.9+(仅使用 Python 标准库,无需安装第三方依赖)
将 12306 通知邮件导出(上文飞书文档)的 txt 文件放入 data/ 目录。
python3 scripts/parse_12306.py --input-dir data --output out命令行参数:
--input-dir <目录>:指定包含 txt 文件的目录(自动扫描所有*.txt)--inputs <文件1> <文件2> ...:显式指定多个 txt 文件路径--output <目录>:指定输出目录(默认:out)--no-report:不生成 HTML 报表(仅生成 JSON 数据)
解析完成后,会在输出目录生成:
合并数据:
out/events.jsonl- 事件级数据out/tickets.json- 票面级数据out/metadata.json- 元信息、去重与坐标覆盖out/journeys.json- 行程级数据、同行成员及票面状态out/report.html- 可视化报表(双击打开)out/map.html- 行程地图(双击打开)
分文件数据:
out/by_file/<文件名>/- 每个 txt 文件单独一份数据(含独立报表)
如果你想了解“从 txt 到离线报表/离线地图”是怎么做出来的,见:
docs/TECH_PATH.md
打开 report.html 后可以:
- 统计总览:行程、车站、车次、多人同行、票面记录
- TOP10:车站、车次、区间排行榜
- 比例分析:车次类型分布、席别分布
- 时间趋势:按月统计趟数和金额
- 筛选查询:按年份/月份、时间范围、车次、车站、价格、席别、状态、同行范围筛选
- 明细表格:可展开查看订单号、事件类型、办理日期等详情
- events.jsonl:每行一个 JSON 对象,代表一封票务邮件(含 tickets 数组)
- tickets.json:JSON 数组,每张票一条记录(已展平,便于统计)
- metadata.json:解析器版本、输入文件列表、统计摘要
- active(未退改):正常购票,未被退票或改签
- refunded(已退票):购票后被退票
- rescheduled(已改签):购票后被改签
默认统计口径为 all_events(统计所有发生过的事件),即使后来退票/改签,原始购票记录也会保留并标注状态。
- 数据隐私:
data/目录下的 txt 文件包含个人信息,已配置.gitignore防止误上传 - 无座处理:所有形如 "N车无座" 的席别会被统一归类为 "无座"
- 候补兑现:候补购票成功兑现的事件会被视为一次购票,计入购票总量
- 时间维度:报表中的年份/月份筛选默认按开车时间,而非购票时间
当有新的 txt 文件时:
- 将新文件放入
data/目录 - 重新运行解析器:
python3 scripts/parse_12306.py --input-dir data --output out - 所有数据会自动合并,按规范化邮件正文去重,并生成新的报表。重复来源与行号会保留。
复制 atlas.example.json 为 atlas.local.json,填写主乘车人 owner 与同行专题的两人 pair。HTML 仅展示主乘车人的记录及共同区间内的专题同伴;原始解析 JSON 保留完整输入。未配置时使用示例姓名。
页面采用暖白旅行图册,提供大地图、同行专题、年月趋势、排行榜、票务来源详情与响应式布局。页尾保留 ON THE SAME TRACK. 和 made by h2o2。
ECharts 5.6.0 随源码提供,LICENSE 和 NOTICE 位于 scripts/vendor。以下资源由使用者在本地准备,未随本次提交分发:
- scripts/vendor/china.geojson:有权使用的中国省级边界,Feature 属性 name 应为地区名称。
- data/station_coords.json:站名映射到经度、纬度数组;键与票面站名一致,例如上海虹桥站。
- 可选字体 scripts/vendor/hannotate-sc.woff2 和 macintosh-skeletal-filled.woff2;缺失时使用系统字体。
缺少地图资源时页面会显示提示,票务筛选和详情仍可使用。生成后的 HTML 内联全部可用资源,不依赖 CDN。
增加可选参数 --railway-data,指定自己保存的路路通 an.db 更新包或 APK:
python3 scripts/parse_12306.py --input-dir data --output out --railway-data /path/to/an.db
参考径路按主车次号及上下车区间匹配,列表显示线路摘要,详情显示分段线路;铁路线搜索及匹配状态与地图、指标、明细联动。每条参考保留数据包版本,历史日期未核验;不同候选径路不自动择一。地图曲线仍为站点连线示意。
也可直接静态查询安装包:
python3 scripts/inspect_lltskb.py /path/to/an.db --train C3029 --from-station 安吉 --to-station 上海南
工具不会安装或执行 APK,安装包、原始数据库与提取数据不随源码发布。
python3 -B -m unittest discover -s tests -v
node --check scripts/templates/atlas.js
模板位于 scripts/templates,解析和生成仅依赖 Python 标准库。通用测试使用虚构票务数据;私人验收结果和生成产物保持在 Git 忽略目录。发布边界见 docs/GITHUB_RELEASE.md。
