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

如何使用Puppeteer访问封闭Shadow DOM内部的元素?

能否用Puppeteer访问封闭Shadow DOM内部元素?

可以实现,但常规方法(直接读取shadowRoot、>>>选择器)对封闭Shadow DOM无效——因为规范明确closed模式下,外部无法通过元素的shadowRoot属性获取引用。我们可以通过篡改原生attachShadow方法的方式,提前保存封闭shadowRoot的引用。

解决方案原理

在页面加载任何脚本之前,注入代码重写HTMLElement.prototype.attachShadow:当组件调用attachShadow({mode: "closed"})时,除执行原生逻辑外,把生成的shadowRoot挂载到元素的自定义属性上,后续就能通过这个属性访问封闭Shadow DOM内容。

实现代码

修改后的Puppeteer脚本

import puppeteer from "puppeteer";

async function start() {
  const browser = await puppeteer.launch({
    headless: true,
  });

  const page = await browser.newPage();

  // 在页面加载前注入脚本,重写attachShadow
  await page.evaluateOnNewDocument(() => {
    const originalAttachShadow = HTMLElement.prototype.attachShadow;
    HTMLElement.prototype.attachShadow = function(options) {
      const shadowRoot = originalAttachShadow.call(this, options);
      // 封闭模式下,将shadowRoot存入自定义属性
      if (options.mode === "closed") {
        this.__closedShadowRoot = shadowRoot;
      }
      return shadowRoot;
    };
  });

  await page.goto("http://localhost:8080/iframe-test-nested.html");

  // 读取封闭Shadow DOM的innerHTML
  const innerHTML = await page.evaluate(() => {
    const container = document.querySelector("body layout-container");
    return container?.__closedShadowRoot?.innerHTML;
  });
  console.log(innerHTML); // 输出包含<div>This is what I want</div>的内容

  // 直接定位内部元素并获取文本
  const targetText = await page.evaluate(() => {
    const container = document.querySelector("body layout-container");
    const div = container?.__closedShadowRoot?.querySelector("div");
    return div?.textContent;
  });
  console.log(targetText); // 输出"This is what I want"

  await browser.close();
}

start();

有效性说明

Puppeteer的evaluateOnNewDocument会在页面上下文初始化后、任何脚本执行前注入代码,所以重写逻辑会先于自定义元素定义执行。当组件创建封闭Shadow DOM时,我们的代码会偷偷保存shadowRoot引用,绕过了规范限制。

注意:这属于hack手段,依赖篡改浏览器原生API,可能随浏览器版本更新失效,但目前在Chrome/Chromium(Puppeteer默认浏览器)中稳定可行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:25:19