Puppeteer无法点击希尔顿酒店网站下一页按钮问题
解决Puppeteer点击希尔顿网站下一页按钮失败的问题
问题分析
你遇到的Error: Node is either not clickable or not an HTMLElement通常由以下原因导致:
- 元素未完全渲染或处于不可见状态
- 选择器定位到了不可点击的子元素(如span、path)而非实际可点击的button节点
- 滚动后分页组件尚未加载完成
- 元素被页面其他元素遮挡
解决方案
1. 使用正确的选择器定位可点击按钮
直接定位到下一页的button元素,而非内部的文本或图标节点。针对希尔顿网站的DOM结构,下一页按钮的有效选择器可以是:
const nextPageSelector = '#results-pagination button.m-pagination-next:not([disabled])';
2. 等待元素完全可见并可点击
用page.waitForSelector替代page.$,确保元素加载完成且处于可交互状态,避免因元素未就绪导致的点击失败:
// 滚动到底部后,先等待分页组件加载 await page.waitForSelector('#results-pagination', { visible: true }); // 等待下一页按钮可见且可点击,超时时间设为5秒 try { await page.waitForSelector(nextPageSelector, { visible: true, timeout: 5000 }); console.log("下一页按钮已准备好"); } catch (err) { console.log("没有更多页面了"); return; }
3. 执行可靠的点击操作
优先使用page.click()方法,它会自动处理元素的可见性和可点击性,比直接调用元素的click()方法更稳定:
// 点击下一页按钮 await page.click(nextPageSelector); // 等待页面导航完成,根据页面加载方式可调整等待策略 await page.waitForNavigation({ waitUntil: 'networkidle2' });
完整修正后的代码
// 滚动到页面底部 await scroll_to_bottom_of_page(page); // 定义下一页按钮选择器 const nextPageSelector = '#results-pagination button.m-pagination-next:not([disabled])'; try { // 等待分页组件和下一页按钮加载完成 await page.waitForSelector('#results-pagination', { visible: true, timeout: 5000 }); await page.waitForSelector(nextPageSelector, { visible: true, timeout: 5000 }); // 点击下一页 console.log("开始点击下一页"); await page.click(nextPageSelector); // 等待页面跳转完成 await page.waitForNavigation({ waitUntil: 'networkidle2' }); } catch (err) { console.log("已到达最后一页或按钮加载失败:", err.message); }
额外排查点
- 如果网站有动态加载或动画效果,可在滚动后添加短暂等待:
await page.waitForTimeout(1000); - 检查是否有弹窗或遮罩层遮挡按钮,可通过以下代码判断元素是否被隐藏:
const isHidden = await page.$eval(nextPageSelector, el => el.offsetParent === null); if (isHidden) console.log("按钮被隐藏"); - 确保Puppeteer使用真实浏览器的用户代理,避免被反爬机制拦截:
const browser = await puppeteer.launch({ args: ['--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"'] });
内容的提问来源于stack exchange,提问作者Nelson Mak
相关产品推荐
相关产品推荐

