关于 chase-travel
用于搜索 Chase Travel 门户航班和酒店的命令行技能,可返回现金与积分价格、Points Boost 优惠及 Chase Edit 福利。适合比较门户预订、现金票价和航空公司转点;搜索需使用 Patchright 和有头浏览器。
主要功能
- 01搜索航班和酒店
- 02显示现金、积分及混合支付价格
- 03查找 Points Boost 优惠
- 04识别 Chase Edit 酒店福利
- 05支持短信与应用推送双重验证
- 06以 JSON 导出结果
适用场景
- 01将门户价格与现金票价比较
- 02评估积分兑换与转点价值
- 03查找提供 Edit 福利的酒店
- 04预订前查看航班选项
MCP 相关
输入将其描述为旅行搜索技能,未说明 MCP 集成。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ borski/ travel-hacking-toolkit --skill chase-travel安装后在 Claude Code 中输入/chase-travel确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
Dockerfilescripts/record_search.pysearch_flights.pytests/test_2fa_method.py详细介绍
Chase Travel Portal Search
通过 Patchright 搜索 Chase Ultimate Rewards 旅行门户中的航班和酒店。返回现金价格、UR 积分价格、Points Boost 优惠以及 Chase Edit 酒店礼遇。
需要 Patchright(一个不易被检测到的 Playwright 分支)。Chase 会拦截标准 Playwright 和 agent-browser。
必须以有头模式运行(headless=False)。 Chase 能检测到无头浏览器。在 macOS 上,Chrome 窗口会短暂出现。要在后台运行,请使用 Docker。
Prerequisites
pip install patchright && patchright install chromium
或者使用 Docker(无需本地安装):
docker pull ghcr.io/borski/chase-travel:latest
# or build locally:
docker build -t chase-travel skills/chase-travel/
When to Use
- 将 UR 门户价格与现金价格和奖励票价格进行比较
- 查看 Points Boost 优惠(部分预订可享 1.5 至 2.0 倍 cpp)
- 查找提供 100 美元酒店消费额度和每日早餐的 Chase Edit 酒店
- 比较使用积分支付与转移积分至航空公司的价值
When NOT to Use
- 完成购买。 仅查找航班和酒店。请勿预订。
- 非 Chase 卡。 此技能需要 Sapphire Reserve 或 Sapphire Preferred 卡。
Card Selection
脚本会自动从账户选择器中选择 Sapphire Reserve 卡(旅行消费可享动态 Points Boost 定价;CSR 通常约为 1.5-2.0 cpp,但不保证最低值;可享 Edit 酒店礼遇)。如果找不到 Reserve,则改用 Sapphire Preferred。只有这些卡才能显示 Edit 酒店礼遇和旅行门户价格。
Usage
Flight Search
# Local (opens a Chrome window briefly)
python3 scripts/search_flights.py --origin SFO --dest CDG --depart 2026-08-11
# Round-trip business
python3 scripts/search_flights.py --origin SFO --dest CDG --depart 2026-08-11 --return 2026-09-02 --cabin business
# JSON output
python3 scripts/search_flights.py --origin SFO --dest CDG --depart 2026-08-11 --json
# Docker
docker run --rm \
-v ~/.chase-travel-profiles:/profiles \
-v /tmp:/tmp/host \
-e CHASE_USERNAME -e CHASE_PASSWORD \
ghcr.io/borski/chase-travel script /scripts/search_flights.py \
--origin SFO --dest CDG --depart 2026-08-11 --cabin business --json
Hotel Search
# Local
python3 scripts/search_flights.py --hotel --dest "Paris" --checkin 2026-08-11 --checkout 2026-08-15
# Docker
docker run --rm \
-v ~/.chase-travel-profiles:/profiles \
-v /tmp:/tmp/host \
-e CHASE_USERNAME -e CHASE_PASSWORD \
ghcr.io/borski/chase-travel script /scripts/search_flights.py \
--hotel --dest "Oslo" --checkin 2026-08-13 --checkout 2026-08-15 --json
Record Mode (API Discovery)
在手动搜索期间捕获网络流量。适用于调试或发现新的 API 端点。
# Local only (needs interactive browser)
python3 scripts/record_search.py
2FA Flow
Chase 使用短信 或 移动应用推送进行 2FA(部分账户仅支持推送)。首次登录时,必须手动完成 2FA。此后,设备信任会持续生效(使用同一配置文件再次运行时会跳过 2FA)。脚本会自动检测账户支持的方式,并采用相应流程。
工作原理: 触发 2FA 时,脚本会向标准输出打印以下两个标记之一,然后最多轮询 3 分钟:
2FA_CODE_NEEDED— 短信。Chase 已发送短信验证码;请提供该验证码(见下文)。MOBILE_APP_APPROVAL_NEEDED— 移动应用推送。没有验证码;用户需在 Chase 移动应用中批准登录,页面解除后脚本便会继续。
面向 Agent(短信): 看到 2FA_CODE_NEEDED 时,请向用户索要 Chase 刚发送到其手机上的短信验证码。用户提供验证码后,将其写入验证码文件:
echo "12345678" > /tmp/chase-2fa-code.txt
脚本会自动读取该文件并继续登录。
面向 Agent(移动推送): 看到 MOBILE_APP_APPROVAL_NEEDED 时,请告知用户在 Chase 移动应用中批准登录——无需输入验证码。脚本会轮询最多 3 分钟,等待批准生效,然后继续运行。
命令钩子(可选,用于完全自动化): 将 CHASE_2FA_COMMAND 设置为一条命令,使其等待验证码并将验证码打印到标准输出。脚本会运行此命令,而不是轮询文件。(仅适用于短信流程。)
Docker: 使用 -v /tmp:/tmp/host 共享临时目录。脚本会检查 /tmp/host/chase-2fa-code.txt 和 /tmp/chase-2fa-code.txt。
首次成功登录并信任设备后,后续运行将跳过 2FA。
凭据必须是已解析的值
CHASE_USERNAME/CHASE_PASSWORD 到达此脚本时必须包含实际用户名和密码。如果你将密钥保存在密钥管理器中,请在启动前将引用解析到环境变量中(大多数密钥管理器都提供了专门用于此目的的 exec/run 包装器)。
未解析的引用(字面形式的 scheme://vault/item 占位符)会被输入登录表单,Chase 随后会回复“我们找不到该用户名和密码。请重试。”——这很容易被误认为是机器人检测。(其实不是:使用真实凭据,从 Docker 发起的新自动登录可以正常工作;这一点已于 2026 年 7 月实时验证,包括保存的 Cookie 已过期时。)
对于这两种错误,脚本都会快速失败:当凭据看起来仍是密钥引用,或 Chase 报告找不到用户名/密码时,它会向标准输出打印 CHASE_BAD_CREDENTIALS(并在 2FA 状态文件中写入 BAD_CREDENTIALS)。**对于 Agent:**不要在遇到此哨兵值时重试——修正凭据的注入方式,然后重新运行。
工作原理
航班搜索架构
- **身份验证:**Patchright 处理登录、2FA、Cookie 持久化和卡片选择。账户标识符会从门户 URL 自动提取。
- **会话:**向
v1/session/create发送POST请求,建立 CXL 旅行会话。标识符会从 Cookie 中自动提取。 - **搜索 API:**向 Chase 的内部 CTE API 发送
POST请求,创建航班搜索会话(返回sessionId) - **结果:**浏览器导航至
travelsecure.chase.com/results/flights/outbound?ssid={sessionId}&cnxtoken={redirectionToken}。脚本通过page.on('response')拦截 API 响应,以捕获legwiseResultsJSON - **分页:**通过 JS 点击 Shadow DOM 中的“显示更多”按钮(
<orxe-button>),加载所有航班(每次 10 个) - **积分加成:**启用 Shadow DOM 切换开关(
<orxe-toggle class="points-offer">)。解析加成卡片轮播,以获取折扣后的积分价格
酒店搜索架构
- **搜索 API:**向 Chase 的酒店搜索端点发送
POST请求,创建会话 - **结果:**浏览器导航至结果页。脚本拦截
hotel/v1.0/search/resultsAPI 响应 - **Edit 检测:**带有
prm[].c == "Signature Amenities"的酒店属于 Edit 酒店。从嵌入式 JSON 中提取权益 - **加成检测:**带有
rwd[].rdp.rcm.t.ofr.d == "Points offer applied"的酒店可享有积分加成 - **分页:**与航班相同的 Shadow DOM 模式
数据结构
航班结果包括:
- 现金价格、积分价格以及现金加积分的混合定价
- 积分加成优惠,包括加成前后的积分成本
- 票价类别(经济舱、基础经济舱、商务标准舱、商务灵活舱等)
- 航班航段信息,包括航空公司、时间、时长、经停次数、机型
- 退款和改签政策
酒店结果包括:
- 每晚及总现金价格
- 积分价格
- Edit 计划会员权益及具体权益(早餐、抵用金、升级)
- 积分加成的可用情况和价格
- 星级、地址、设施、退款政策
输出格式
始终使用 Markdown 表格。
航班
| # | 航空公司 | 航线 | 经停 | 时长 | 现金 | 积分 | 加成 | CPP |
|---|---|---|---|---|---|---|---|---|
| 1 | Air France | SFO-CDG | 直飞 | 10h 40m | $5,397 | 539,683 | 269,841 | 2.0 |
酒店
| # | 酒店 | 计划 | 每晚 | 总计 | 积分 | 权益 |
|---|---|---|---|---|---|---|
| 1 | Sommerro | EDIT, BOOST | $408 | $816 | 81,600 | 早餐、$100 抵用金、升级 |
表格之后
- 标明哪些酒店属于 Edit(并列出权益)
- 计算积分兑换的 CPP
- 标记积分加成优惠及其有效 cpp
- 尽可能与直接预订价格进行比较
- 获取结账时实际的积分加成报价。CSR 定价是动态的,并非固定倍数。
门户定价说明
- CSR 上的 Chase 门户定价采用动态 Points Boost。过去固定的 1.5x 倍数已不再适用。每次预订都会显示具体的积分价格;CSR 上的实际 cpp 通常在 1.5-2.0 cpp 范围内,但并非每次预订都能保证达到这一底线。
- Points Boost 优惠会以独立卡片的形式显示,并提供折扣后的积分价格(实际 cpp 通常为 1.5x 到 2.0x)。
cash_plus_points定价会用完所有可用的 UR 积分,剩余部分以现金支付。- Chase 会话不会在关闭浏览器后保留。每次运行 Docker 都需要重新登录(但如果设备已受信任,则会跳过 2FA)。
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
CHASE_USERNAME | 是 | Chase 网银用户名 |
CHASE_PASSWORD | 是 | Chase 网银密码 |
CHASE_2FA_COMMAND | 否 | 阻塞运行直到短信验证码就绪,并将验证码打印到 stdout 的命令 |
CHASE_PROFILE | 否 | 浏览器配置文件目录(默认:~/.chase-travel-profiles/default) |
故障排查
- 在 Docker 中登录页面显示“Access Denied”: Chase 会阻止来自 Docker 的
secure01ea.chase.com访问。脚本改用chase.com首页登录(使用不同的身份验证端点,可在 Docker 中正常工作)。 - 视频模态框阻挡点击: 脚本包含一个 MutationObserver,可自动移除模态框。如果模态框仍然存在,该观察器会处理重新渲染的情况。
- 直接调用 API 时出现 CSRF 错误: travelsecure.chase.com 结果 API 需要由 React 应用管理的 CSRF 令牌。脚本使用响应拦截,而不是直接调用 API,因此完全避开了 CSRF。
- 未找到航班: Chase 可能尚未加载结果。脚本会通过拦截等待 API 响应,因此不应出现这种情况。请检查是否已成功登录。
限制
- 必须使用有头模式。 Chase 能检测无头模式。解决办法是使用 Docker+xvfb。
- 每次搜索约需 30 秒。 包括登录、门户导航、搜索和加载结果。
- 浏览器关闭后会话即失效。 会话不会保留。每次运行都需要登录(首次信任设备后会跳过 2FA)。
- React 受控输入框。 表单自动化不可靠。脚本通过 API 调用创建搜索,而不填写表单。