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);
代码说明
- 先获取所有酒店的容器节点
[id^="property-record-map-"],每个容器对应一个酒店; - 遍历每个容器,在容器内部单独查询名称、价格、距离元素,避免全局查询导致的重复;
- 使用
?.可选链操作符避免元素不存在时抛出错误,同时设置默认空值保证数据结构完整性。
如果某个酒店容器内的价格元素有特定的父级(比如.rate-display),可以进一步细化价格选择器,比如container.querySelector('.rate-display .t-price'),确保只获取有效价格。
内容的提问来源于stack exchange,提问作者Nelson Mak
相关产品推荐
相关产品推荐

