📖 知识点
1. 穿透的核心思路
要拿暗影里的元素,不能一把梭,得两步走:
- 先定位host 元素(密室的门,在明面 DOM 里,能定位到)
- 从 host 进入 shadow root,再定位内部元素
2. DrissionPage 穿透写法
DrissionPage 支持通过 host 元素进入其 shadow root:
# 1. 定位host元素
host = page.ele("某个host选择器")
# 2. 进入host的shadow root,再定位内部元素
inner = host.ele("shadow:内部选择器") # 或用专用穿透写法
关键在于:先拿到 host,再从 host 里找内部元素,DrissionPage 会识别 shadow root 并穿透进去。
3. 用 locator 穿透(进阶写法)
有些版本支持更直接的穿透语法:
# 定位到shadow root里的元素
ele = page.ele("css:选择器", timeout=...)
# 若元素在shadow里,可用穿透前缀进入
inner = page.ele("shadow:...")
具体写法随版本略有差异,核心记住 "host → shadow 内" 的钻取思路即可。
完整示例
from DrissionPage import ChromiumPage
page = ChromiumPage()
page.get("含ShadowDOM的网址")
# 暗影穿透咒:先定位host元素
host = page.ele(".shadow-host")
print("🎯 已定位到host元素:", host.tag)
# 再进入host的shadow root,定位内部元素
inner = host.ele("内部元素选择器")
if inner:
print("✅ 穿透成功,暗影内元素:", inner.text)
else:
print("❌ 未找到暗影内元素,检查内部选择器")
⚠️ 易错提醒
- 别跳过 host 直接找内部元素,普通选择器进不了密室
- 有多层 ShadowDOM 嵌套时,要一层层钻(host→shadow→host→shadow…)
- 内部元素的选择器是相对 shadow 内部的,不是整页的
⚔️ Kata 实战任务
任务需求:
- 导入 ChromiumPage
- 访问含 ShadowDOM 的练习页
https://the-internet.herokuapp.com/shadowdom - 定位 host 元素(练习页暗影宿主是
my-paragraph之类的自定义标签) - 从 host 进入 shadow root,定位暗影内部元素
- 读取并打印暗影内元素的文字
参考代码
from DrissionPage import ChromiumPage
page = ChromiumPage()
page.get("https://the-internet.herokuapp.com/shadowdom")
print("🌐 已打开ShadowDOM练习页")
# 暗影穿透咒1:定位host元素(暗影宿主)
host = page.ele("my-paragraph")
print("🎯 已定位到host元素:", host.tag)
# 暗影穿透咒2:从host进入shadow root,定位内部元素
try:
# 该练习页暗影内有若干 text 元素
inner = host.ele("text:Hello Shadow DOM")
if inner:
print("✅ 穿透成功,暗影内元素:", inner.text)
else:
print("❌ 未找到,尝试其他内部选择器")
except Exception as e:
print(f"❌ 穿透过程异常:{e}")
print("📖 提示:需确认host已定位,且内部选择器相对shadow内部")
运行输出(示意):
🌐 已打开ShadowDOM练习页
🎯 已定位到host元素: my-paragraph
✅ 穿透成功,暗影内元素: Hello Shadow DOM
🧠 思考题
- 定位 ShadowDOM 内部元素的完整套路是哪两步?为什么必须先定位 host?
- 如果 ShadowDOM 有嵌套(密室套密室),该怎么逐层穿透?
行者孙Python