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

如何使用Puppeteer在Shadow DOM中选择下拉选项?

解决Puppeteer操作Shadow DOM内下拉选项的问题

你当前代码的问题在于:获取到Shadow Root的ElementHandle后,直接调用了select方法,但这个方法是针对<select>元素的,而非Shadow Root本身。要操作Shadow DOM里的下拉框,得先定位到内部的<select>元素,再执行选择操作。

以下是两种可行的解决方式:

方式一:直接在page.evaluate内完成选择操作

这种方式更简洁,直接在浏览器上下文里访问Shadow DOM并操作下拉框:

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    defaultViewport: null,
    args: ["--start-maximized"],
  });

  const page = await browser.newPage();
  await page.goto("https://mixam.co.uk/");
  await page.waitForNetworkIdle();

  // 直接在浏览器上下文中操作Shadow DOM内的select
  await page.evaluate(() => {
    const shadowRoot = document.querySelector(
      "body > div.bg-pastel-lavender > div:nth-child(1) > div > div.h-min-650.h-100 > div > price-calculator"
    ).shadowRoot;
    const sizeSelect = shadowRoot.querySelector("#Size");
    sizeSelect.value = "4-NONE";
    // 触发change事件(如果页面依赖这个事件更新内容)
    sizeSelect.dispatchEvent(new Event("change"));
  });

  // 可按需添加等待逻辑,确保操作生效
  // await page.waitForTimeout(2000);

  await browser.close();
})();

方式二:通过ElementHandle定位Shadow DOM内的select元素

如果需要保留ElementHandle的操作方式,需先从Shadow Root中获取<select>元素的Handle,再调用select方法:

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    defaultViewport: null,
    args: ["--start-maximized"],
  });

  const page = await browser.newPage();
  await page.goto("https://mixam.co.uk/");
  await page.waitForNetworkIdle();

  // 获取Shadow Root的ElementHandle
  const shadowRootHandle = await page.evaluateHandle(() => {
    return document.querySelector(
      "body > div.bg-pastel-lavender > div:nth-child(1) > div > div.h-min-650.h-100 > div > price-calculator"
    ).shadowRoot;
  });

  // 从Shadow Root中获取select元素的Handle
  const sizeSelectHandle = await shadowRootHandle.$("#Size");
  // 调用select方法选择选项
  await sizeSelectHandle.select("4-NONE");

  // 可按需添加等待逻辑,确保操作生效
  // await page.waitForTimeout(2000);

  await browser.close();
})();

注意事项

  • 部分页面会依赖下拉框的change事件更新内容,因此设置value后,建议手动触发该事件(方式一中已包含)。
  • 若页面加载较慢,可增加等待元素出现的逻辑,比如在evaluate内添加判断元素存在的循环,或结合page.waitForSelector使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:27:35