酒店搜索服务

HotelZero是一个使用Playwright浏览器自动化技术从Booking.com搜索酒店的服务,提供80多种过滤选项以实现精准搜索。

  • by insprd
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 insprd/hotelzero

使用说明

零号酒店

一个MCP(模型上下文协议)服务器,使用Playwright浏览器自动化在Booking.com上搜索酒店。提供80多种过滤器选项,用于精确的酒店搜索。

特性

  • 综合过滤:80多个过滤器,涵盖物业类型、设施、可达性、活动等
  • 真实Booking.com数据:使用从URL参数反向工程的实际Booking.com过滤代码
  • 赞助商广告过滤:自动排除付费/促销列表(包含以下内容的原生广告 nad_ 跟踪)
  • 智能评分:结果根据其与您的标准的匹配程度进行评分和排名
  • 匹配透明度:每个结果都显示了它与您的过滤器匹配的原因

安装

npm install -g hotelzero

# Install Playwright browser (Chromium)
npx playwright install chromium

或者直接使用npx运行:

npx hotelzero

代理支持

对于频繁使用或避免IP阻止,您可以通过以下方式配置代理服务器 HOTELZERO_PROXY 环境变量:

# HTTP proxy
HOTELZERO_PROXY=http://proxy.example.com:8080 npx hotelzero

# HTTP proxy with authentication
HOTELZERO_PROXY=http://user:pass@proxy.example.com:8080 npx hotelzero

# SOCKS5 proxy
HOTELZERO_PROXY=socks5://proxy.example.com:1080 npx hotelzero

# SOCKS5 proxy with authentication
HOTELZERO_PROXY=socks5://user:pass@proxy.example.com:1080 npx hotelzero

配置代理后,您将在启动日志中看到确认:

Proxy enabled: http://proxy.example.com:8080
HotelZero v1.8.0 running on stdio

日志记录

HotelZero通过以下方式使用结构化日志记录 皮诺。日志会写入stderr,以避免干扰MCP stdio传输。

日志级别

通过以下方式控制日志的冗长程度 HOTELZERO_LOG_LEVEL 环境变量:

# Available levels: trace, debug, info, warn, error, fatal, silent
# Default: info

# Debug mode - verbose output for troubleshooting
HOTELZERO_LOG_LEVEL=debug npx hotelzero

# Silent mode - no logs
HOTELZERO_LOG_LEVEL=silent npx hotelzero

# Error only - minimal output
HOTELZERO_LOG_LEVEL=error npx hotelzero

日志输出

日志采用JSON格式,便于解析:

{"level":"info","time":"2026-02-15T12:00:00.000Z","service":"hotelzero","module":"server","version":"1.11.0","transport":"stdio","msg":"HotelZero server started"}
{"level":"info","time":"2026-02-15T12:00:01.000Z","service":"hotelzero","module":"browser","msg":"Browser initialized"}
{"level":"info","time":"2026-02-15T12:00:02.000Z","service":"hotelzero","module":"browser","destination":"Paris","msg":"Starting hotel search"}

会话保持

HotelZero会自动保存浏览器会话数据(Cookie、本地存储),以减少机器人检测并避免重复的验证码挑战。

运作原理

  • 每次成功请求后,会话都会自动保存
  • 启动时,加载上一个会话(如果可用)
  • 默认会话位置: ~/.hotelzero/session.json

自定义会话路径

使用 HOTELZERO_SESSION_PATH 要指定自定义位置,请执行以下操作:

# Custom session file location
HOTELZERO_SESSION_PATH=/path/to/session.json npx hotelzero

# Disable session persistence (use empty string)
HOTELZERO_SESSION_PATH="" npx hotelzero

清除会话

如果遇到问题,可以删除会话文件:

rm ~/.hotelzero/session.json

快速开始

作为MCP服务器运行

添加到您的MCP客户端配置中(例如,Claude Desktop、OpenCode):

{
  "mcpServers": {
    "hotelzero": {
      "command": "npx",
      "args": ["hotelzero"]
    }
  }
}

可用工具

find_hotels

搜索具有全面过滤功能的酒店。这是拥有所有80多个过滤选项的主要工具。

例子:

{
  "destination": "San Juan, Puerto Rico",
  "checkIn": "2026-03-07",
  "checkOut": "2026-03-14",
  "beachfront": true,
  "freeWifi": true,
  "fitness": true,
  "minRating": 8
}

search_hotels

无过滤器的基本酒店搜索。当您不需要特定条件时,请将此用于简单查询。

例子:

{
  "destination": "Paris, France",
  "checkIn": "2026-06-01",
  "checkOut": "2026-06-05",
  "guests": 2,
  "rooms": 1
}

get_hotel_details

获取特定酒店的详细信息,包括完整的设施列表、描述和照片。

例子:

{
  "url": "https://www.booking.com/hotel/pr/condado-vanderbilt.html"
}

完整的筛选器参考

基本搜索参数

参数 类型 必填 说明
destination string 是 城市或地点(例如,“波多黎各圣胡安”)
checkIn string 是 入住日期(YYYY-MM-DD)
checkOut string 是 退房日期(YYYY-MM-DD)
guests number No 客人数量(默认值:2)
rooms number No 房间数(默认值:1)
currency string 否 货币代码(美元、欧元、英镑、日元等)默认值:美元
sortBy enum 否 排序结果: popularity, price_lowest, price_highest, rating, distance

评级和价格

筛选器 类型 描述
minRating number 最低评价分数:6=愉快,7=良好,8=非常好,9=精彩
minPrice number 每晚最低价格
maxPrice number 每晚最高价格

物业类型

筛选器 类型 选项
propertyType enum hotel, apartment, resort, villa, vacation_home, hostel, bnb, guesthouse, homestay, motel, inn, lodge, chalet, campground, glamping, boat, capsule, ryokan, riad, country_house, farm_stay
starRating 数字 1、2、3、4或5颗星

海滩和位置

筛选器 类型 描述
beachfront boolean 属性直接在海滩上
beachAccess boolean 房产可以进入海滩
oceanView boolean 海景客房
maxDistanceFromCenter enum half_mile, 1_mile, 2_miles

酒店设施

筛选器 描述
freeWifi 酒店各处均提供免费WiFi
pool 室内游泳池
spa 水疗/健康中心
fitness 健身中心/健身房
parking 停车位可用
restaurant 现场餐厅
bar 现场酒吧/休息室
roomService 24小时前台/客房服务
airportShuttle 机场班车服务
hotTub 热水浴缸/按摩浴缸
sauna 桑拿
garden 花园
terrace 露台
nonSmokingRooms 提供无烟客房
familyRooms 家庭房
evCharging 电动汽车充电站
casino 赌场
golf 附近的高尔夫球场(2英里以内)
tennis 网球场
bbqFacilities 烧烤设施
laundry 洗衣服务
concierge 礼宾服务
businessCenter 商务中心

客房设施

筛选器 描述
airConditioning 空调
kitchen 厨房或小厨房
balcony 私人阳台
privatePool 私人泳池
privateBathroom 私人浴室
bath 浴缸
tv 电视
minibar 迷你吧
safe 室内保险箱
washingMachine 单元内洗衣机
soundproofing 隔音客房

床型

筛选器 选项
bedType king, queen, double, twin, single

膳食计划

筛选器 描述
breakfast 早餐已包含在房价内
allInclusive 全包套餐
selfCatering 自助式厨房设施

住宿类型和政策

筛选器 描述
petFriendly 允许携带宠物
adultsOnly 仅限成人入住
lgbtqFriendly LGBTQ+友好(Booking.com旅游自豪)
freeCancellation 免费取消
noPrepayment 无需提前还款
noBookingFee 无信用卡预订

可持续性

筛选器 描述
sustainabilityCertified 具有可持续性认证

活动

筛选器 描述
snorkeling 提供浮潜服务
diving 潜水/水肺潜水
fishing 钓鱼可用
hiking 附近的远足径
cycling 自行车/自行车可用
skiing 附近滑雪
waterSports 提供水上运动
horseRiding 可骑马

可达性-物业级别

筛选器 描述
grabRails 浴室扶手
raisedToilet 高架厕所
loweredSink 水槽降低
braille 盲文标牌
tactileSigns 触觉标志
auditoryGuidance 听觉指导

无障碍设施-客房级别

筛选器 描述
wheelchairAccessible 整个单元轮椅无障碍
groundFloor 底层单元可用
elevatorAccess 上层可乘电梯到达
walkInShower 步入式淋浴间
rollInShower 无障碍淋浴间(轮椅无障碍)
showerChair 淋浴椅可用

连锁酒店

筛选器 选项
hotelChain marriott, hilton, hyatt, ihg, wyndham, best_western, accor, choice, radisson, ritz_carlton, four_seasons, fairmont, sheraton, westin, w_hotels, courtyard, residence_inn, hampton, embassy_suites, doubletree

查询示例

波多黎各海滩度假

{
  "destination": "San Juan, Puerto Rico",
  "checkIn": "2026-03-07",
  "checkOut": "2026-03-14",
  "beachfront": true,
  "freeWifi": true,
  "fitness": true,
  "pool": true,
  "minRating": 8
}

豪华滑雪场

{
  "destination": "Aspen, Colorado",
  "checkIn": "2026-01-15",
  "checkOut": "2026-01-22",
  "propertyType": "resort",
  "starRating": 5,
  "skiing": true,
  "spa": true,
  "hotTub": true,
  "minRating": 9
}

全包家庭海滩之旅

{
  "destination": "Cancun, Mexico",
  "checkIn": "2026-07-01",
  "checkOut": "2026-07-08",
  "guests": 4,
  "rooms": 2,
  "beachfront": true,
  "allInclusive": true,
  "familyRooms": true,
  "pool": true,
  "freeCancellation": true
}

无障碍市中心酒店

{
  "destination": "London, UK",
  "checkIn": "2026-04-01",
  "checkOut": "2026-04-05",
  "maxDistanceFromCenter": "half_mile",
  "wheelchairAccessible": true,
  "elevatorAccess": true,
  "walkInShower": true,
  "freeWifi": true
}

宠物友好公路旅行站

{
  "destination": "Portland, Oregon",
  "checkIn": "2026-05-10",
  "checkOut": "2026-05-12",
  "petFriendly": true,
  "parking": true,
  "freeCancellation": true,
  "maxPrice": 200
}

数字游牧者长期住宿

{
  "destination": "Lisbon, Portugal",
  "checkIn": "2026-06-01",
  "checkOut": "2026-06-30",
  "propertyType": "apartment",
  "kitchen": true,
  "freeWifi": true,
  "washingMachine": true,
  "maxDistanceFromCenter": "1_mile",
  "maxPrice": 150
}

浪漫之旅

{
  "destination": "Santorini, Greece",
  "checkIn": "2026-09-15",
  "checkOut": "2026-09-20",
  "adultsOnly": true,
  "oceanView": true,
  "privatePool": true,
  "breakfast": true,
  "spa": true,
  "minRating": 9
}

日本文化体验

{
  "destination": "Kyoto, Japan",
  "checkIn": "2026-04-01",
  "checkOut": "2026-04-07",
  "propertyType": "ryokan",
  "breakfast": true,
  "minRating": 8
}

环保探险

{
  "destination": "Costa Rica",
  "checkIn": "2026-02-01",
  "checkOut": "2026-02-08",
  "sustainabilityCertified": true,
  "hiking": true,
  "snorkeling": true,
  "diving": true
}

高尔夫之旅

{
  "destination": "Scottsdale, Arizona",
  "checkIn": "2026-03-01",
  "checkOut": "2026-03-05",
  "propertyType": "resort",
  "golf": true,
  "spa": true,
  "restaurant": true,
  "bar": true
}

运作原理

服务器端过滤

过滤器通过Booking.com应用 nflt 使用反向工程过滤代码的URL参数。例如:

  • beachfront: true 添加 ht_beach=1
  • freeWifi: true 添加 hotelfacility=107
  • fitness: true 添加 popular_activities=11
  • minRating: 8 添加 review_score=80

客户端评分

在获取结果后,每家酒店都会根据其与您的标准的匹配程度进行评分:

  • +20分:当房产提到海滩时,与海滩相关的过滤器
  • +15分:评分9.0+(“优秀”)
  • +10分:每个配套设施(WiFi、游泳池、健身房等)
  • +5分:500+条评论(可信度奖励)

结果按比赛分数排序,因此最佳比赛首先出现。

赞助商广告过滤

Booking.com在搜索结果中注入付费的“原生广告”。这些是通过以下方式识别和排除的:

  1. 检测 nad_ 酒店卡HTML或链接中的(原生广告跟踪)
  2. 检查是否有明确的“广告”、“赞助”或“推广”标签

这确保了你只看到自然结果,而不是付费广告。


输出格式

每家酒店的结果包括:

1. Hotel Name
   Price: $XXX per night
   Rating: X.X/10 Rating Text (XXX reviews)
   Location: X.X miles from center
   Amenities: Pool, Free WiFi, Gym, ...
   Match Score: XX
   Why it matches: Near beach, Has WiFi, Has gym, ...
   Book: https://www.booking.com/hotel/...

技术细节

建筑

src/
├── index.ts      # MCP server with tool definitions
├── browser.ts    # Playwright automation & filter mappings
└── test*.ts      # Test scripts

依赖项

  • @modelcontextprotocol/sdk -MCP服务器SDK
  • playwright -浏览器自动化
  • zod -架构验证

浏览器配置

  • 无头模式:运行时没有可见的浏览器窗口
  • 反检测:自定义用户代理和禁用的自动化标志
  • 用户代理轮换:在每个会话中从14个真实的浏览器配置文件(Chrome、Firefox、Safari、Edge)中随机选择
  • 自动滚动:通过滚动页面加载更多结果
  • 弹出窗口处理:自动关闭cookie横幅和登录模式

筛选器代码映射

所有Booking.com过滤代码都映射到 browser.ts:

const FILTER_CODES = {
  propertyType: { hotel: "ht_id=204", resort: "ht_id=206", ... },
  hotelfacility: { freeWifi: 107, pool: 433, spa: 54, ... },
  roomfacility: { airConditioning: 11, kitchen: 999, ... },
  popularActivities: { fitness: 11, golf: 12, skiing: 13, ... },
  chaincode: { marriott: 1080, hilton: 1078, ... },
  // ... 20+ filter categories
};

局限性

  • 速率限制:Booking.com可能会限制或阻止自动请求
  • 结果上限:每次搜索返回约25个结果(第一页+滚动加载)
  • 价格准确性:价格可能因可用性和时间而异
  • 过滤器可用性:某些筛选器可能不适用于所有目的地

故障排除

“浏览器未初始化”

跑 npx playwright install chromium 安装浏览器。

npx playwright install chromium

如果这不起作用,请尝试强制重新安装:

npx playwright install chromium --force

未返回任何结果

  • 检查日期:确保入住/退房日期在未来
  • 验证目的地:尝试更具体的地点,比如“法国巴黎”,而不仅仅是“巴黎”
  • 减少过滤器:过多的筛选器可能导致零匹配-尝试删除一些
  • 检查可用性:有些目的地可能没有您的日期

验证码或访问被拒绝

如果您遇到验证码挑战:

  1. 等待5-10分钟 重试之前
  2. 检查您的会话:删除会话文件,然后重试
    rm ~/.hotelzero/session.json
    
  3. 使用代理:考虑配置代理服务器(请参阅 代理支持)
  4. 降低请求频率:避免快速提出许多请求

被Booking.com屏蔽

  • 速率限制:请等待几分钟,然后重试
  • 会议议题:清除会话文件(rm ~/.hotelzero/session.json)
  • IP已阻止:使用代理服务器或从其他网络尝试
  • 用户代理轮换:HotelZero会自动轮换用户代理,但一个IP的过度使用仍会触发阻止

代理不工作

  • 验证可访问性:使用测试代理 curl 第一
    curl -x http://proxy:8080 https://www.booking.com
    
  • 检查凭据:如果用户名/密码包含特殊字符,请确保它们是URL编码的
  • 协议支持:确保代理支持HTTPS连接
  • 连接超时:某些代理可能很慢-请尝试其他代理

价格或数据缺失

  • 动态负载:一些数据异步加载;尝试增加超时时间
  • 货币问题:明确指定货币 currency: "USD"
  • 区域差异:某些地区的某些房产可能不会显示价格

会话问题

如果您遇到不一致的行为:

# Clear the session and start fresh
rm ~/.hotelzero/session.json

# Or disable session persistence entirely
HOTELZERO_SESSION_PATH="" npx hotelzero

调试模式

启用调试日志记录以查看详细信息:

HOTELZERO_LOG_LEVEL=debug npx hotelzero

这将显示:

  • 正在请求URL
  • 正在应用过滤器
  • 找到的结果数量
  • 任何错误或警告

测试失败

如果您正在运行测试套件,但测试失败:

  1. 网络问题:测试点击live Booking.com-检查您的连接
  2. 速率限制:在测试运行之间等待几分钟
  3. 选择器更改:Booking.com可能已更新其HTML结构

API响应架构

酒店结果(来自 find_hotels / search_hotels)

interface HotelResult {
  name: string;                    // Hotel name
  price: number | null;            // Price per night as number (null if not shown)
  priceDisplay: string;            // Formatted price string (e.g., "$199")
  rating: number | null;           // Review score 0-10 (null if no reviews)
  ratingText: string;              // Rating description (e.g., "Excellent", "Very Good")
  reviewCount: number | null;      // Number of reviews (null if not shown)
  location: string;                // Neighborhood/area name
  distanceToCenter: string;        // Distance from center (e.g., "0.5 miles from center")
  amenities: string[];             // Detected amenities (e.g., ["Pool", "Free WiFi", "Spa"])
  highlights: string[];            // Special highlights (e.g., ["Free Cancellation"])
  link: string;                    // Full Booking.com URL for the hotel
  thumbnailUrl: string | null;     // Hotel thumbnail image URL (null if not available)
  availability: string | null;     // Availability status (e.g., "Only 2 rooms left!")
  matchScore?: number;             // Relevance score based on filters (only with filters)
  matchReasons?: string[];         // Why this hotel matched (only with filters)
}

酒店详情(来自 get_hotel_details / compare_hotels)

interface HotelDetails {
  name: string;                    // Hotel name
  url: string;                     // Booking.com URL
  rating: number | null;           // Review score 0-10
  ratingText: string;              // Rating description
  reviewCount: number | null;      // Total number of reviews
  starRating: number | null;       // Official star rating 1-5
  address: string;                 // Full address
  description: string;             // Hotel description text
  highlights: string;              // Property highlights summary
  pricePerNight: number | null;    // Price per night as number
  priceDisplay: string;            // Formatted price per night
  totalPrice: string;              // Total stay price (formatted)
  checkInTime: string;             // Check-in time (e.g., "15:00")
  checkOutTime: string;            // Check-out time (e.g., "11:00")
  popularFacilities: string[];     // Top facilities list
  allFacilities: string[];         // Complete facilities list
  roomTypes: string[];             // Available room type names
  photos: string[];                // Photo URLs
  nearbyAttractions: string[];     // Nearby points of interest
  guestReviewHighlights: string[]; // Notable review excerpts
  locationInfo: string;            // Location description
}

可用性结果(来自 check_availability)

interface AvailabilityResult {
  available: boolean;              // Whether rooms are available
  hotelName: string;               // Hotel name
  checkIn: string;                 // Check-in date (YYYY-MM-DD)
  checkOut: string;                // Check-out date (YYYY-MM-DD)
  guests: number;                  // Number of guests searched
  rooms: number;                   // Number of rooms searched
  roomOptions: RoomOption[];       // Available room types
  lowestPrice: number | null;      // Lowest price found
  lowestPriceDisplay: string;      // Formatted lowest price
  message: string;                 // Status message
  url: string;                     // Booking URL with dates
}

interface RoomOption {
  name: string;                    // Room type name
  price: number | null;            // Price as number
  priceDisplay: string;            // Formatted price
  sleeps: number | null;           // Maximum occupancy
  features: string[];              // Room features
  bedType: string;                 // Bed configuration
  cancellation: string;            // Cancellation policy
  breakfast: string;               // Meal plan info
}

评论结果(来自 get_reviews)

interface ReviewsResult {
  hotelName: string;               // Hotel name
  overallRating: number | null;    // Overall score 0-10
  totalReviews: number;            // Total review count
  ratingBreakdown: RatingBreakdown; // Scores by category
  reviews: Review[];               // Individual reviews
  url: string;                     // Hotel URL
}

interface RatingBreakdown {
  staff: number | null;            // Staff rating
  facilities: number | null;       // Facilities rating
  cleanliness: number | null;      // Cleanliness rating
  comfort: number | null;          // Comfort rating
  valueForMoney: number | null;    // Value rating
  location: number | null;         // Location rating
  freeWifi: number | null;         // WiFi rating
}

interface Review {
  title: string;                   // Review title
  rating: number | null;           // Individual score 0-10
  date: string;                    // Review date
  travelerType: string;            // Traveler type (e.g., "Couple", "Family")
  country: string;                 // Reviewer's country
  stayDate: string;                // When they stayed
  roomType: string;                // Room they booked
  nightsStayed: string;            // Length of stay
  positive: string;                // Positive comments
  negative: string;                // Negative comments
}

价格日历结果(来自 get_price_calendar)

interface PriceCalendarResult {
  hotelName: string;               // Hotel name
  startDate: string;               // Calendar start (YYYY-MM-DD)
  endDate: string;                 // Calendar end (YYYY-MM-DD)
  nights: number;                  // Number of nights checked
  currency: string;                // Currency code
  prices: DatePrice[];             // Price for each date
  lowestPrice: number | null;      // Lowest price in range
  lowestPriceDate: string | null;  // Date with lowest price
  highestPrice: number | null;     // Highest price in range
  highestPriceDate: string | null; // Date with highest price
  averagePrice: number | null;     // Average price
  url: string;                     // Hotel URL
}

interface DatePrice {
  date: string;                    // Date (YYYY-MM-DD)
  price: number | null;            // Price as number
  priceDisplay: string;            // Formatted price
  available: boolean;              // Whether available
  currency: string;                // Currency code
}

错误响应

当发生错误时,响应包括:

interface ErrorResponse {
  content: [{
    type: "text";
    text: string;                  // Error message with code and help text
  }];
  isError: true;
}

错误代码:

  • BROWSER_NOT_INITIALIZED -先调用init()
  • NAVIGATION_FAILED -页面加载失败
  • RATE_LIMITED -请求太多
  • CAPTCHA_DETECTED -遇到验证码挑战
  • NO_RESULTS -搜索未返回任何结果
  • DESTINATION_NOT_FOUND -目的地无效
  • NETWORK_ERROR -连接问题
  • TIMEOUT -请求超时
  • BLOCKED -Booking.com拒绝访问

许可证

麻省理工学院