📖 知识点
1. 什么是 ShadowDOM?
ShadowDOM(影子 DOM):一种把元素 "封闭封装" 的机制。网页的一部分被包进一个独立、隔离的子树里,形成 "影子",让样式和结构自成一体,不与外界冲突。
💡 生活比喻 ShadowDOM 像一栋楼里单独隔出的密室。外面的人看不到密室里的房间布局,只能看到密室的门(host 元素),进不去就找不到里面的东西。
2. 为什么普通选择器找不到?
普通 page.ele("选择器") 默认只在外层 "明面"DOM 里找元素。而 ShadowDOM 里的元素被隔离在 "影子根(shadow root)" 里,对外层而言是不可见的,所以普通选择器定位不到:
# 这样直接找,可能找不到
ele = page.ele(".shadow-inner-element")
# 往往返回None
3. 关键概念
| 概念 | 说明 |
|---|---|
| host 元素 | 承载 ShadowDOM 的 "宿主" 元素(密室的门) |
| shadow root | 影子根,隔离区的入口 |
| 内部元素 | 藏在隔离区里的元素,普通选择器够不到 |
💡 理解
- ShadowDOM 把元素 "藏" 进隔离区,外部 DOM 看不到内部
- 要找内部元素,需要先定位 host 元素 → 穿过 shadow root → 再定位内部元素
- DrissionPage 提供穿透机制(Day38 实战)
⚠️ 易错提醒
- 找不到元素时,除了检查 iframe,还要想到 "会不会在 ShadowDOM 里"
- 普通
page.ele()定位不到 ShadowDOM 内部元素,别反复试同一个选择器- 需要先找到 host 元素,再往暗影里钻
⚔️ Kata 实战任务
任务需求:
- 导入 ChromiumPage
- 访问一个含 ShadowDOM 的练习页(如
https://the-internet.herokuapp.com/shadowdom) - 用普通选择器定位 ShadowDOM 内部的元素
- 观察:直接定位往往找不到(返回 None)
- 打印提示,理解 "为什么普通选择器够不到暗影里的元素"
参考代码
from DrissionPage import ChromiumPage
page = ChromiumPage()
# 访问含ShadowDOM的练习页
page.get("https://the-internet.herokuapp.com/shadowdom")
print("🌐 已打开ShadowDOM练习页")
# 尝试用普通选择器直接定位ShadowDOM内部元素
# (该练习页暗影里有若干 text 元素)
shadow_text = page.ele("text:Hello Shadow DOM")
if shadow_text:
print("🎯 直接定位到:", shadow_text.text)
else:
print("❌ 普通选择器找不到ShadowDOM内部元素(返回None)")
print("📖 原因:内部元素被隔离在shadow root里,外层DOM看不见")
运行输出(示意):
🌐 已打开ShadowDOM练习页
❌ 普通选择器找不到ShadowDOM内部元素(返回None)
📖 原因:内部元素被隔离在shadow root里,外层DOM看不见
💡 观察:直接定位暗影内的元素往往扑空。别灰心,明天学穿透咒就能进密室了。
🧠 思考题
- ShadowDOM 里的元素为什么普通选择器找不到?"隔离" 体现在哪里?
- 找网页元素失败时,除了考虑 iframe,还要排查哪一类 "藏匿" 结构?