You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Marriott网站Puppeteer爬取价格重复问题求助

问题:Puppeteer爬取万豪官网搜索结果时价格重复导致数组错乱

问题描述

使用Puppeteer从万豪官网搜索结果页提取酒店名称、价格和距离时,执行page.$$eval('[id^="property-record-map-"] .t-price', elements => elements.map(el => el.textContent.trim()))获取价格会返回重复值(如555、555、736、736),导致价格数组长度和名称、距离数组不一致,最终结果错乱。

复现步骤

  • 进入万豪官网,输入目的地与入住日期;
  • 点击Find Hotels后,勾选Show rates with taxes and all fees和Show available hotels only。

已尝试方案

  • 移除textContent的trim()处理,无效;
  • 指定完整class名[class="t-price m-display-block "],返回错误价格。

解决方案

出现重复价格的核心原因是每个酒店条目对应的DOM容器中存在多个.t-price元素(比如页面渲染时的冗余节点、不同展示逻辑的价格副本),全局提取所有.t-price会导致价格数组长度翻倍。

正确的做法是先定位每个酒店的独立容器,再在每个容器内单独提取名称、价格、距离,确保三个字段一一对应。修改后的代码如下:

// 直接提取结构化的酒店数据数组,每个元素包含name、price、distance
const hotels = await page.$$eval('[id^="property-record-map-"]', (containers) => {
  return containers.map(container => {
    // 在当前酒店容器内查找对应的元素
    const name = container.querySelector('span.l-property-name')?.textContent.trim() || '';
    // 选择容器内第一个.t-price(或根据实际DOM结构调整选择器,确保每个容器只取一个价格)
    const price = container.querySelector('.t-price')?.textContent.trim() || '';
    const distance = container.querySelector('.js-hotel-distance.l-hotel-distance')?.textContent.trim() || '';
    
    return { name, price, distance };
  });
});

// 现在hotels数组中的每个元素都是对应酒店的完整信息,不会出现字段错乱
console.log(hotels);

代码说明

  1. 先获取所有酒店的容器节点[id^="property-record-map-"],每个容器对应一个酒店;
  2. 遍历每个容器,在容器内部单独查询名称、价格、距离元素,避免全局查询导致的重复;
  3. 使用?.可选链操作符避免元素不存在时抛出错误,同时设置默认空值保证数据结构完整性。

如果某个酒店容器内的价格元素有特定的父级(比如.rate-display),可以进一步细化价格选择器,比如container.querySelector('.rate-display .t-price'),确保只获取有效价格。

内容的提问来源于stack exchange,提问作者Nelson Mak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 11:18:22