
pricewin-hotel-deal-finder
通过比较 Booking.com、Agoda、Google Hotels 和 OpenTravel 上任意城市和任意日期的实时价格,找到最便宜的酒店优惠——一条命令即可返回按最佳性价比、最便宜和品质精选排序的结果,并附带直接预订链接,所有价格均统一为美元。当有人询问酒店价格、酒店优惠、最便宜的房间或房价、最佳酒店价格、酒店价格比较,或哪个 OTA 更便宜时使用——例如“Booking 和 Agoda 哪个去东京更便宜”、“帮我找曼谷 100 美元以下的酒店”、“比较 8 月 12 日至 15 日的酒店价格”、“新宿附近最便宜的酒店”。
通过比较 Booking.com、Agoda、Google Hotels 和 OpenTravel 上任意城市和任意日期的实时价格,找到最便宜的酒店优惠——一条命令即可返回按最佳性价比、最便宜和品质精选排序的结果,并附带直接预订链接,所有价格均统一为美元。当有人询问酒店价格、酒店优惠、最便宜的房间或房价、最佳酒店价格、酒店价格比较,或哪个 OTA 更便宜时使用——例如“Booking 和 Agoda 哪个去东京更便宜”、“帮我找曼谷 100 美元以下的酒店”、“比较 8 月 12 日至 15 日的酒店价格”、“新宿附近最便宜的酒店”。
PriceWin 酒店优惠查找器
一条命令即可比较 Booking.com、Agoda、Google Hotels 和 OpenTravel 的实时酒店价格——并返回按最佳性价比、最便宜和品质精选排序的结果,附带直接预订链接。
无需打开五个 OTA 标签页来寻找真正的最低价。让您的智能体执行 “帮我找东京 8 月 12 日至 15 日、2 位客人的酒店”,此技能将在约 30–60 秒内(缓存城市)返回一份清晰、排序的比较结果。
在以下问题中调用此技能:
- “
<city>在<dates>期间最便宜的酒店是哪家?” - “这家酒店在 Booking.com 和 Agoda 上哪个更便宜?”
- “比较
<city>、<N>位客人的酒店价格。” - “帮我找
<city>每晚低于<X>美元的酒店。” - “
<dates>期间<landmark>附近性价比最高的住宿?”
每个问题都会返回下面相同的单命令答案——无需来回澄清。
一条命令即可获得:
- 🥇 最佳性价比 · 🥈 最便宜 · 🥉 品质精选——并列展示
- 来自最多 4 个来源 的每晚实际价格,统一为 美元
- 可点击的预订链接,直接跳转到每家酒店最便宜的 OTA
- 适用于全球任何城市——包括反爬严格的城市(上海、杭州、曼谷等),通过隐秘的 Patchright 守护进程实现
- 无需 API 密钥,无需 MCP 服务器——只需
node/npx
示例结果:
🏨 东京 • 8月12日–15日 • 3晚 • 2位客人
━━━━━━━━━━━━━━━━━━━━
🥇 最佳性价比
新宿格兰贝尔酒店
✅ agoda 💰 $118/晚
booking 💰 $131/晚
→ 比 Booking 节省 $13
🥈 最便宜
APA 新宿酒店
✅ google 💰 $94/晚
📊 18家酒店 | agoda, booking, google, opentravel • 价格以美元计
安装:
npx skills add https://github.com/Price-Win/pricewin-skills-hub --skill pricewin-hotel-deal-finder
如何使用此技能
一条命令即可完成全部工作——通常无需先问澄清问题。推断参数(如下)并运行:
cd {baseDir} && node bin/search.js "<city>" <checkInYYYY-MM-DD> <checkOutYYYY-MM-DD> <adults> en-us
{baseDir} 是此技能的安装目录(由运行时自动解析)。如果您的运行时未替换它,请 cd 进入包含此 SKILL.md 的文件夹(即包含 bin/search.js 的文件夹)。避免硬编码 ~/.hermes/... 或 ~/.openclaw/... 路径——不同平台路径不同。
示例:
cd {baseDir} && node bin/search.js "Hangzhou" 2026-06-10 2026-06-13 2 en-us
脚本会自动处理所有事情:守护进程启动、Agoda 缓存查找、Google + Booking 内联搜索、OpenTravel API 查找(所有城市)、新城市发现以及格式化的层级卡片输出。运行它并将输出发送给用户。
推断参数而非询问(仅当城市或日期确实不明确时才询问):
- 年份: 除非用户另有说明,否则使用今天的日期所在的当前年份。如果请求的月份/日期今年已过,则假定为明年。(如果不确定,使用
date +%Y-%m-%d获取今天的日期。) - “10-13/6” →
<year>-06-10 <year>-06-13——根据上述规则填充<year> - “2位客人”/“2人” →
2位成人 - 区域设置: 传递给 OTA 的语言/地区代码(控制网站语言和地区)。默认为
en-us。价格以美元计(Google Hotels 使用gl=us&curr=USD请求);其他来源遵循您传递的区域设置。
一次 search.js 运行就是整个工作流程——无需在其上使用 Python、curl 或临时爬虫。
操作规则——如何获得可靠结果
规则 0 — 仅通过 search.js(通过您的终端/shell 工具)驱动浏览器。原生浏览器工具在此处无效。 此技能依赖于一个隐秘的 Patchright 守护进程。运行时的原生工具——browser_navigate / browser_open、browser_click、browser_type / browser_fill、browser_snapshot、browser_close、任何其他 browser_* 以及子智能体委托(delegate_task / spawn_agent)——在此任务上会失败,因此不要使用它们:
- 这些原生工具会启动一个没有隐秘功能的普通 Chromium,因此 Booking.com 和 Agoda 会在几秒内检测到机器人;请求会挂起直到运行时杀死它们(“命令在 30/60 秒后超时”)。这会浪费 5 分钟以上且无任何返回。
search.js启动的 Patchright 守护进程能够通过机器人检测。 - 委托的子智能体从空历史和没有技能上下文开始,因此它们会退回到 Python/curl 爬虫,但会立即被机器人拦截。在当前智能体中运行此技能。
唯一可行的方法:
cd {baseDir} && node bin/search.js ...
规则 1 — 让 search.js 进行爬取;不要自己爬取 OTA。 避免直接调用 browse.js、在浏览器中执行 goto/click/type、手动构建 Agoda/Booking/Google URL、单独调用 OpenTravel API 或自己启动守护进程。search.js 已经通过一个精心设计的流程驱动隐秘守护进程,能够通过机器人检测——它内部处理每个城市的 Agoda 发现(包括上海、杭州等中国城市)。手动导航 OTA 是失败的首要原因:它会触发 Agoda/Booking 的反机器人机制(“检测到自动化”、“重定向到主页”、“完成搜索时出现问题”)并导致 IP 被屏蔽。运行一次 search.js 并发送其输出。如果某个来源看起来“缺失”,请参考规则 4,而不是手动获取。
规则 2 — 首次城市发现需要 2–4 分钟。 如果 search.js 输出包含 "discovering" 或 "launching" 消息,请告诉用户:“首次搜索此城市——正在发现选择器,大约需要 2–4 分钟……”并等待结果,而不是重试或中止。
规则 3 — 精确发送输出。 search.js 输出格式化的层级卡片,可直接发送。将输出直接复制到您的回复中。不要重新格式化、总结或缩写。
规则 3a — 保留 Markdown 超链接。 输出中的每个酒店名称已包装为 [Hotel Name](https://booking-url...)——一个可点击的超链接。保持其完整:不要将 URL 拆分为单独的 🔗 https://... 行,不要将 [Hotel Name](url) 替换为纯文本,保持 OTA 名称小写(“google”,而非“Google”),并保持章节标题原样(“📋 更多优惠”)。输出已准备好用于 Telegram-MarkdownV2;逐字发送可为用户提供可点击的酒店名称和隐藏的 URL(界面整洁)。
规则 3b — 在您自己的评论中也使用超链接酒店名称。 如果您在输出后添加建议或评论部分,请使用脚本为该酒店打印的相同 URL,将您提到的每个酒店名称包装为 [Hotel Name](url),而不是纯文本。
规则 4 — 部分结果是正常的——直接发送,不要手动修复。 某个来源可能在一次运行中缺失(例如 Agoda 本次被屏蔽,或 OpenTravel 没有该城市的库存)。这没问题——发送带有现有来源的层级卡片;页脚(📊 N hotels | <sources> • prices in USD)精确列出了找到的内容。通过浏览器或直接 URL 获取缺失的来源往往会触发反机器人机制并使情况更糟,因此避免这样做。如果 search.js 完全出错,用一行告诉用户失败原因,并显示它在错误之前打印的任何部分输出。为了获得更多覆盖,唯一可靠的重试是再次运行相同的 search.js 命令(反机器人机制通常是暂时的)。
输出格式参考
search.js 按以下格式打印层级卡片——您直接将其发送给用户:
酒店名称是其最便宜 OTA 的 Markdown 链接。价格行不包含链接,OTA 键以小写显示(agoda/booking/google/opentravel)。没有星级评分或区域行——脚本没有这些数据。
🏨 <city> • <d1>–<d2> • <N>晚 • <adults>位客人
━━━━━━━━━━━━━━━━━━━━
🥇 最佳性价比
[<Hotel Name>](<cheapest_link>)
✅ agoda 💰 <price>/晚
booking 💰 <price>/晚
opentravel 💰 <price>/晚
→ 比 Booking 节省 <diff>
🥈 最便宜
[<Hotel Name>](<cheapest_link>)
✅ google 💰 <price>/晚
agoda 💰 <price>/晚
🥉 品质精选
[<Hotel Name>](<cheapest_link>)
✅ booking 💰 <price>/晚
agoda 💰 <price>/晚
📋 更多优惠
— Agoda —
• [<Hotel>](<agoda_link>) — agoda: <price> | booking: <price>
— Booking —
• [<Hotel>](<booking_link>) — booking: <price>
— Google —
• [<Hotel>](<google_link>) — google: <price>
— OpenTravel —
• [<Hotel>](<opentravel_link>) — opentravel: <price>
💡 提示:<best Hotel Name>
[在 <OTA> 上预订](<link>) — <price>/晚
📊 <N> 家酒店 | <有数据的来源> • 价格以美元计
所有价格均以美元显示。Agoda、Google 和 OpenTravel 会根据 IP 锁定为越南盾,并通过实时汇率转换;Booking 原生返回美元。页脚中仅列出实际返回数据的来源。
限制
- 每个城市的首次搜索需要支付 Agoda 发现成本(2–4 分钟)。Google 和 Booking 是内联的(无需发现);OpenTravel 是直接 API 调用。
- 后续搜索会重用 Agoda 缓存,并在约 30–60 秒内完成。
安全与数据处理
在本地运行,无需 API 密钥,不收集个人数据——唯一发送出去的数据是搜索查询(城市、日期、客人)。爬取的酒店文本被视为不可信:bin/search.js 中的 sanitizeText() 会在任何内容到达模型输出之前剥离控制字符、零宽字符、双向文本和 Markdown 控制字符,并且预订链接限制为 http(s)。运行的命令、下载和网络出口的完整披露见 SECURITY.md。





