Excel Selenium VBA中使用XPath获取元素信息失败问题
问题描述
- 抓取目标网站人员姓名信息时元素定位失败,浏览器开发者工具中查看DOM结构,目标节点为
<b> User : Piquemal Bruno</b> - 直接对该节点生成XPath,仅返回路径
/html/body/table/tbody/tr/td[2]/table/tbody/tr[1]/td[2]/b,缺失frameset、frame、#document相关的上层路径 - 编写VBA+Selenium测试代码运行后,目标元素集合返回空值;位于
#document节点之前的banner命名元素可正常定位,判断是#document节点阻断了查找路径 - 已尝试标签定位、CSS选择器等多种定位方式,均无法命中目标元素

原测试代码如下:
Sub GetUserInfo() Dim k As WebElements Dim h As WebElement Dim FindBy As New Selenium.By EdgeWeb.get """INTERNET PAGE THAT I WANT""" Set h = EdgeWeb.FindElementByName("banner") Set k = EdgeWeb.FindElements(FindBy.XPath("/html/frameset/frame/document/html/body/table/tbody/tr/td[2]/table/tbody/tr[1]/td[2]/b")) Debug.Print k.Count End Sub
故障原因
这个问题的核心是frame框架的DOM隔离机制:开发者工具中看到的#document是frame加载的独立文档,和主页面分属两个完全独立的DOM树。Selenium默认在主页面DOM上下文执行查询,无法直接穿透到frame内部,你写的XPath里带的document是调试工具显示的文档边界标记,不是可被XPath识别的DOM节点,所以查询必然返回空。
解决方法
操作frame内部元素前,必须先将Selenium的上下文切换到目标frame,再执行元素查询即可,修改后的可运行代码如下:
Sub GetUserInfo() Dim k As WebElements Dim h As WebElement Dim targetFrame As WebElement Dim FindBy As New Selenium.By EdgeWeb.Get "目标网页地址" ' 定位承载目标内容的frame元素,可根据实际场景换用name、src、id等属性定位 Set targetFrame = EdgeWeb.FindElementByTag("frame") ' 切换到frame内部文档上下文 EdgeWeb.SwitchToFrame targetFrame ' 切换后直接用开发者工具生成的短XPath查询即可,不需要拼接frameset/frame/document前缀 Set k = EdgeWeb.FindElements(FindBy.XPath("/html/body/table/tbody/tr/td[2]/table/tbody/tr[1]/td[2]/b")) Debug.Print k.Count ' 如果后续需要操作主页面元素,执行下面语句切回默认上下文即可 ' EdgeWeb.SwitchToDefaultContent End Sub
注意事项
- 如果页面存在多层frame嵌套,需要从最外层到最内层逐层切换,不能直接跳转至内层frame
- 若frame没有稳定的定位属性,可以按索引切换,比如页面第一个frame传参0即可:
EdgeWeb.SwitchToFrame 0 - XPath/CSS路径中不需要写入
#document节点,该标记不属于DOM结构的可查询节点
内容的提问来源于stack exchange,提问作者zaretyp
相关产品推荐
相关产品推荐

