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

Puppeteer JS中无法点击href跳转新页面的问题求助

使用Puppeteer JS点击页面href链接的问题

我尝试用Puppeteer JS点击页面中的href链接,代码如下:

await page.goto('https://example.net/search/images?search=real+estate+postcards');
await page.waitForSelector(".GridItem-item-tVq", {visible: true});

const els = await page.$$(".GridItem-item-tVq");

els.forEach(async el => {
  const href = await el.$eval('a', a => a.getAttribute('href'));
  await page.click(href)
})

打印href得到的结果是:

/gallery/93911757/High-End-Real-Estate-Postcard-Design/modules/542619723
/gallery/69359021/Postcard-Design/modules/492523237
/gallery/158597277/Post-Card-Design/modules/894845353
/gallery/126032017/Real-Estate-Agent-Postcard/modules/715550465

这些路径对应的完整链接是example.com/gallery/xxx,可正常访问。但点击时出现错误:

'Document': '/gallery/93911757/High-End-Real-Estate-Postcard-Design/modules/542619723' is not a valid selector.

后来尝试直接点击元素:

await page.click(el)

又报错:

error: selector.startsWith is not a function

请问如何正确获取a元素并实现点击?


解决方案

错误原因分析

  1. page.click()方法仅接受CSS选择器字符串,传入URL路径会被判定为无效选择器,导致报错。
  2. page.click()不支持直接传入ElementHandle对象,必须使用ElementHandle自身的click()方法。

方法一:调用ElementHandle的click()方法

从父元素中获取a标签的ElementHandle,再调用其内置的click方法:

await page.goto('https://example.net/search/images?search=real+estate+postcards');
await page.waitForSelector(".GridItem-item-tVq a", {visible: true});

const els = await page.$$(".GridItem-item-tVq");

// 用for...of实现串行处理,避免forEach并行执行导致的页面冲突
for (const el of els) {
  const linkEl = await el.$('a');
  await linkEl.click();
  // 等待页面跳转完成
  await page.waitForNavigation();
  // 如需继续点击下一个链接,回到搜索页并重新等待元素加载
  await page.goto('https://example.net/search/images?search=real+estate+postcards');
  await page.waitForSelector(".GridItem-item-tVq a", {visible: true});
}

方法二:直接定位所有目标a标签

跳过父元素,直接选择页面中的目标a标签,简化代码逻辑:

await page.goto('https://example.net/search/images?search=real+estate+postcards');
await page.waitForSelector(".GridItem-item-tVq a", {visible: true});

const links = await page.$$(".GridItem-item-tVq a");

for (const link of links) {
  await link.click();
  await page.waitForNavigation();
  // 按需返回原搜索页
  await page.goto('https://example.net/search/images?search=real+estate+postcards');
  await page.waitForSelector(".GridItem-item-tVq a", {visible: true});
}

方法三:直接跳转href(无需模拟点击)

如果不需要模拟用户点击的交互动作,仅需访问目标页面,可以直接拼接完整URL用page.goto跳转:

await page.goto('https://example.net/search/images?search=real+estate+postcards');
await page.waitForSelector(".GridItem-item-tVq a", {visible: true});

// 获取完整链接(自动补全域名)
const hrefs = await page.$$eval(".GridItem-item-tVq a", links => links.map(a => a.href));

for (const url of hrefs) {
  await page.goto(url);
  // 执行页面处理逻辑
}

注意事项

  • 避免用forEach结合async/await,会导致所有点击操作并行执行,引发页面状态冲突,建议用for...of实现串行处理。
  • 点击链接跳转后,若需要继续处理下一个链接,必须回到原搜索页并重新等待元素加载,确保元素可被定位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:33:13