vag-Zhao/variflight-scraper
GitHub: vag-Zhao/variflight-scraper
逆向飞常准前端加密协议并实现自动登录与航班数据批量采集的 Python 工具。
Stars: 1 | Forks: 0
# Variflight Flight Data Scraper
## 目录
- [项目背景](#项目背景)
- [功能特性](#功能特性)
- [加密逆向](#加密逆向)
- [项目结构](#项目结构)
- [快速开始](#快速开始)
- [环境要求](#环境要求)
- [安装依赖](#安装依赖)
- [CLI 版本](#cli-版本)
- [GUI 版本](#gui-版本)
- [配置说明](#配置说明)
- [输出格式](#输出格式)
- [接口说明](#接口说明)
- [注意事项](#注意事项)
## 项目背景
`map.variflight.com` 的所有查询接口拒绝明文参数,前端通过 `app.js`(约 2.6 MB,webpack 打包)对每次请求进行 **AES + RSA 双层加密**,服务端只接受加密后的三段式参数格式。
本项目完整逆向了 `app.js` 偏移 ~2 558 000 处的 `encyStr` 函数,用 Python 完全复现了加密流程,实现:
- **免人工干预**的自动登录(含 OCR 识别图形验证码)
- 按日期范围批量查询到达指定机场的所有直飞航班
- 结果导出为 JSON / CSV / xlsx,Excel 可直接打开中文不乱码
## 功能特性
| 功能 | CLI (`nui/`) | GUI (`ui/`) |
|------|:---:|:---:|
| AES-128-CBC + RSA-1024 加密请求 | ✅ | ✅ |
| 自动登录(OCR 识别验证码) | ✅ | ✅ |
| 多日期范围批量查询 | ✅ | ✅ |
| 彩色终端实时输出 | ✅ | ✅ |
| 航线/航班/统计三级数据 | ✅ | — |
| 并发 dexx 查询(4 线程) | ✅ | — |
| 日期选择器(tkcalendar) | — | ✅ |
| 验证码图片实时预览 | — | ✅ |
| 结果表格实时写入 + 列排序 | — | ✅ |
| 导出 JSON + CSV | ✅ | — |
| 导出 xlsx(优先)/ csv | — | ✅ |
## 加密逆向
服务端接口要求请求参数以如下三段式密文发送:
_c=&_r1=&_r2=
完整加密流程:
查询参数字典
│
├─ 序列化为 &k=v 格式明文
├─ secrets 模块随机生成 16 位 AES key 和 16 位 IV(CSPRNG)
├─ AES-128-CBC + ZeroPadding → Base64 密文 _c
├─ RSA-1024 PKCS#1 v1.5 公钥加密 key → Base64 _r1
└─ RSA-1024 PKCS#1 v1.5 公钥加密 IV → Base64 _r2
Python 实现(`nui/core/crypto.py`):
def build_encrypted_params(params: dict) -> str:
plain = "".join(f"&{k}={v}" for k, v in params.items())
key, iv = _rand(), _rand() # 每次请求独立随机密钥
return f"_c={_aes(plain, key, iv)}&_r1={_rsa(key)}&_r2={_rsa(iv)}"
RSA 公钥硬编码于 `app.js`,本项目直接引用,无需运行时下载。
## 项目结构
两套实现完全独立,不共享任何模块:
variflight-scraper/
│
├── nui/ # CLI 版本(命令行 + JSON/CSV 导出)
│ ├── main.py # 入口:参数解析、流程编排
│ ├── config.toml # 查询配置(从 config.toml.example 复制)
│ ├── core/
│ │ ├── crypto.py # AES-128-CBC + RSA-1024 加密实现
│ │ ├── session.py # HTTP 会话、登录、接口封装、重试策略
│ │ ├── models.py # 航司代码 → 中文名映射
│ │ ├── config.py # TOML 配置读取与字段校验
│ │ └── logger.py # 惰性 ANSI 彩色终端日志
│ ├── query/
│ │ ├── api.py # drx/dex/dexx/stx 查询编排(并发 dexx)
│ │ ├── renderer.py # 终端表格渲染(与业务逻辑解耦)
│ │ └── export.py # JSON / CSV 文件导出
│ └── output/ # 查询结果输出目录(自动创建)
│
├── ui/ # GUI 版本(Tkinter 桌面应用)
│ ├── main.py # 入口
│ ├── core/
│ │ ├── crypto.py # AES + RSA 加密(同 nui,独立副本)
│ │ ├── session.py # HTTP 会话 + 机场名称批量加载
│ │ ├── models.py # FlightInfo 数据类 + 机场缓存 + 航司映射
│ │ └── logger.py # 轻量彩色日志(模块加载时检测 TTY)
│ ├── service/
│ │ ├── flights.py # 航班查询业务逻辑(串行,实时输出)
│ │ └── export.py # xlsx / csv 导出(自动选择桌面/下载目录)
│ └── gui/
│ ├── app.py # Tkinter 主窗口(1200×600,含所有 UI 控件)
│ └── session.py # GUIVariflightSession(验证码路由到 GUI)
│
├── airports_china.csv # 中国民航机场 IATA 码数据
├── airports_china.json # 同上,JSON 格式
├── doc/
│ ├── README.md # 本文档(带样式版)
│ └── variflight_encryption_analysis.md # 加密逆向详细分析
├── .gitignore
└── README.md # 本文件
## 快速开始
### 环境要求
- Python **3.9+**(推荐 3.11+,内置 `tomllib` 无需额外安装)
- Windows / macOS / Linux
### 安装依赖
# 核心依赖(必须)
pip install requests pycryptodome rsa
# CLI 可选:OCR 自动识别验证码
pip install ddddocr
# GUI 必须
pip install Pillow tkcalendar openpyxl
# Python < 3.11 需要额外安装 TOML 解析库
pip install tomli
一次性安装全部:
pip install requests pycryptodome rsa ddddocr tkcalendar Pillow openpyxl tomli
### CLI 版本
#### 1. 创建配置文件
复制模板并填写账号:
cp nui/config.toml.example nui/config.toml
编辑 `nui/config.toml`:
[account]
username = "your_username"
password = "your_password"
token = "" # 留空则自动登录;有 token 可直接填入跳过登录
[query]
arr = "HNY" # 到达机场 IATA 码(必填)
dep = "" # 出发机场,留空 = 查全部出发地
date_start = "2026-06-22" # 开始日期
date_end = "2026-06-24" # 结束日期(与 date_start 相同则只查单天)
[output]
save_dir = "" # 留空 = 自动保存到 nui/output/
也可以用环境变量覆盖账号,避免凭证落盘:
export VARIFLIGHT_USERNAME="your_username"
export VARIFLIGHT_PASSWORD="your_password"
#### 2. 运行
python nui/main.py
# 或指定配置文件路径
python nui/main.py --config /path/to/config.toml
### GUI 版本
python ui/main.py
启动后:
1. 填写**用户名 / 密码**
2. 填写**到达机场** IATA 码(如 `HNY`),出发机场留空查全部
3. 通过日期选择器设置查询范围
4. 确认验证码(OCR 自动填充,或手动输入后点「确认」)
5. 点击 **▶ 开始获取**,航班数据实时写入表格
6. 查询完成后自动保存至桌面或下载目录
## 配置说明
| 字段 | 位置 | 说明 | 必填 |
|------|------|------|:----:|
| `username` | `[account]` | 登录账号,可用环境变量 `VARIFLIGHT_USERNAME` 覆盖 | 是* |
| `password` | `[account]` | 登录密码,可用环境变量 `VARIFLIGHT_PASSWORD` 覆盖 | 是* |
| `token` | `[account]` | 已有 session token,填入可跳过登录 | 否 |
| `arr` | `[query]` | 到达机场 IATA 码(2–4 位字母) | 是 |
| `dep` | `[query]` | 出发机场过滤,留空查全部出发地 | 否 |
| `date_start` | `[query]` | 查询起始日期,格式 `YYYY-MM-DD` | 是 |
| `date_end` | `[query]` | 查询结束日期,格式 `YYYY-MM-DD` | 是 |
| `save_dir` | `[output]` | 输出目录,留空则使用 `nui/output/` | 否 |
## 输出格式
### JSON(CLI)
{
"arr": "HNY",
"date_start": "2026-06-22",
"date_end": "2026-06-24",
"generated_at": "2026-06-22 10:30:00",
"days": [
{
"date": "2026-06-22",
"routes": [
{ "dep": "PEK", "arr": "HNY", "is_direct": true, "airline": "中国国航" }
],
"flights": [
{
"dep": "PEK", "arr": "HNY",
"flight_no": "CA1234", "share_code": "",
"dep_time": "08:30", "arr_time": "10:45",
"duration": "2h15m", "next_day": 0,
"airline": "中国国航"
}
],
"stats": {
"total_routes": 10, "total_flights": 48,
"airline_count": 5, "airlines": "国航/南航/东航"
}
}
]
}
### CSV(CLI)
UTF-8 with BOM,Excel 双击可直接打开,列:
日期 | 航班号 | 代码共享 | 出发IATA | 到达IATA | 起飞 | 落地 | 飞行时长 | 跨日天数 | 航司
### xlsx / csv(GUI)
保存至**桌面**(优先)或**下载目录**,文件名格式:
variflight_HNY_20260622_20260624.xlsx
列:`日期 | 航班号 | 出发城市 | 出发IATA | 起飞 | 落地(+跨日) | 航司`
## 接口说明
所有接口均位于 `https://map.variflight.com/public`,参数需加密后传输。
| 接口 | 路径 | 方法 | 说明 |
|------|------|:----:|------|
| 航线列表 | `/drx` | GET | 到达某机场的所有航线(直飞/经停标志) |
| 直飞详情 | `/dex` | POST | 直飞航线 ID + 飞行距离(km) |
| 航班时刻 | `/dexx` | POST | 具体航线的所有航班起降时间 |
| 查询统计 | `/stx` | POST | 总航线数、机场数、航司列表等汇总 |
| 登录 | `/login` | POST | 账号密码 + 图形验证码 |
| 验证码 | `/getCaptcha` | GET | 获取图形验证码图片(PNG) |
## 注意事项
- 本工具仅供授权测试人员内部使用,**请勿用于未授权场景**
- `config.toml` 含有登录凭证,**已加入 `.gitignore`,请勿提交至公开仓库**
- 内置请求间隔 ≥ 300 ms,过度频繁请求可能触发服务端限速(code=10)
- 登录接口含图形验证码,OCR(`ddddocr`)识别成功率约 85–95%,失败时自动降级人工输入
- RSA-1024 为服务端现有方案,本项目忠实复现,不可自行更换密钥长度
## 依赖一览
| 包 | 用途 | 是否必须 |
|----|------|:-------:|
| `requests` | HTTP 会话 | ✅ |
| `pycryptodome` | AES-128-CBC 加密 | ✅ |
| `rsa` | RSA-1024 PKCS#1v1.5 加密 | ✅ |
| `ddddocr` | 验证码 OCR | 可选 |
| `tomli` | TOML 解析(Python < 3.11) | 可选 |
| `tkcalendar` | GUI 日期选择器 | GUI 用 |
| `Pillow` | GUI 验证码图片预览 | GUI 用 |
| `openpyxl` | xlsx 导出 | GUI 用 |
标签:BeEF, Python, 前端逆向, 命令控制, 响应拦截, 数据采集, 无后门, 爬虫, 网络调试, 自动化, 逆向工具