1. 遇到的问题1
图中的<browser>内有个#document,代码无法定位到其中的<dialog>,有可能浏览器开发工具的查看器可以搜到,但是代码中定位不到,甚至可能查看器也搜不到直接复制的XPATH
原因
#document
并不代表一个直接可阅读的文本字符串,而是表示源码中嵌入的一个完整的HTML文档结构,通常出现在查看经过JavaScript动态加载或者嵌套在<iframe>
、<frame>
、<object>
等标签中的网页内容时。我使用爬虫保存的源码,发现也是不包括它的内部代码。
查看器都搜不到直接复制的XPATH表达式,可能是因为正在处理的页面结构与标准的HTML有所不同,<browser>
标签并不是标准HTML的一部分,而是某些特定环境中的元素, 比如Mozilla Firefox的XUL界面,XUL元素通常处于特定的XML命名空间xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"。如果查看器都搜不到直接复制到的XPATH表达式,可以写成忽略命名空间的XPATH表达式。
上图中,直接复制的XPATH表达式,在查看器中搜不到
这时可以写成忽略命名空间的方式,就可以搜到了
但是我使用代码的时候还是定位不到,了解后,可能是因为#document的父元素实际上是一个frame或iframe,需要先切换到这个frame才能定位其内部的元素。
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "browser"))
1.2 遇到的问题2
途中的dialog中有个#shadow-root (open),但是我用查看器和代码都定位不到它内部的元素
原因
#shadow-root
是 Shadow DOM 中的一个概念,当一个元素(称为宿主元素或Shadow Host)附加了一个 Shadow DOM 树时,这个树就被插入到宿主元素的常规DOM树中,但又保持隔离。这意味着,宿主元素的内部实现细节,包括样式和结构,可以与外部环境隔离,从而防止样式冲突和其他潜在的问题。我保存源码,发现也不包括它的内部代码。
Shadow DOM有两种类型:
- 开放型(Open):可以通过JavaScript访问和操作。
- 封闭型(Closed):不能从外部JavaScript访问,提供了更强的封装和安全性。
首先要找到包含#shadow-root (open) 的宿主元素,然后执行JavaScript代码,从而访问Shadow DOM
# 找到Shadow Host,dialog中有一个#shadow-root (open)
shadow_host = driver.find_element(By.XPATH, "//*[local-name()='dialog']")
# 访问Shadow Root中想要定位的元素
shadow_root = driver.execute_script("return arguments[0].shadowRoot.querySelector('.dialog-button-box > button:nth-child(3)')", shadow_host)
其中的 '.dialog-button-box > button:nth-child(3)' 为想要定位的元素的CSS_SELECTOR(在查看器中可能搜不到)