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

如何让Appium的page_source包含Shadow Root元素以适配BeautifulSoup解析?

获取含Shadow DOM的完整HTML方案

核心逻辑

Appium自带的page_source不会包含Shadow DOM内容,因为Shadow DOM是封闭隔离的。要一次性拿到所有嵌套Shadow Root的完整DOM,得通过JavaScript遍历整个DOM树,把每个Shadow Root的内容手动嵌入到对应元素的结构里,再导出处理后的完整HTML字符串,就能用BeautifulSoup正常解析了。

具体实现

第一步:用JS序列化完整DOM(含Shadow DOM)

写一段递归遍历DOM的JS脚本,遇到带Shadow Root的元素时,把Shadow Root内部的HTML插入到元素内容中,最后返回整个文档的HTML:

function serializeWithShadowDOM(element) {
  const clone = element.cloneNode(false);
  Array.from(element.childNodes).forEach(child => {
    if (child.nodeType === Node.ELEMENT_NODE) {
      if (child.shadowRoot) {
        // 递归处理Shadow Root并插入到克隆元素中
        const shadowClone = serializeWithShadowDOM(child.shadowRoot);
        clone.appendChild(shadowClone);
      } else {
        // 普通元素直接递归处理
        clone.appendChild(serializeWithShadowDOM(child));
      }
    } else {
      // 文本节点直接复制
      clone.appendChild(child.cloneNode(true));
    }
  });
  return clone;
}

// 序列化整个文档根节点
const fullDOM = serializeWithShadowDOM(document.documentElement);
return fullDOM.outerHTML;

第二步:Appium执行JS并解析

通过Appium的execute_script方法执行上面的脚本,拿到完整HTML后交给BeautifulSoup处理:

from bs4 import BeautifulSoup

# 执行JS获取包含所有Shadow DOM的完整HTML
full_html = self.driver.execute_script("""
function serializeWithShadowDOM(element) {
  const clone = element.cloneNode(false);
  Array.from(element.childNodes).forEach(child => {
    if (child.nodeType === Node.ELEMENT_NODE) {
      if (child.shadowRoot) {
        const shadowClone = serializeWithShadowDOM(child.shadowRoot);
        clone.appendChild(shadowClone);
      } else {
        clone.appendChild(serializeWithShadowDOM(child));
      }
    } else {
      clone.appendChild(child.cloneNode(true));
    }
  });
  return clone;
}
const fullDOM = serializeWithShadowDOM(document.documentElement);
return fullDOM.outerHTML;
""")

# 用BeautifulSoup解析完整HTML
soup = BeautifulSoup(full_html, "html.parser")
# 现在可以正常搜索所有元素,包括原Shadow DOM里的内容

注意点

  • 这段JS会递归处理所有层级的嵌套Shadow Root,不管嵌套多深都能覆盖。
  • 执行一次JS的开销远低于用Appium逐个操作Shadow元素,完全符合你一次导出本地处理的需求。
  • 如果页面里有<iframe>这类独立文档的元素,可能需要额外处理,但针对Shadow DOM的场景已经足够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 08:52:12