不获取整页源码的webDriver.getPageSource()替代方案是什么
问题背景
当前集成测试场景使用Selenium+Jsoup组合实现元素获取,原有实现通过webDriver.getPageSource()拉取全量页面源码再交给Jsoup解析,执行效率低,需要实现不拉取全量源码、直接选取目标元素且最终返回Jsoup Elements列表的方案。
原有实现代码:
public Elements getElementsByTag(final String tag) { final Document document = Jsoup.parse(webDriver.getPageSource()); return document.getElementsByTag(tag); }
实现方案
核心逻辑是跳过全量页面源码拉取步骤,先用Selenium原生定位能力直接筛选出目标WebElement集合,再逐个提取元素的outerHTML属性交给Jsoup解析,最终组装为标准Jsoup Elements返回。
Selenium调用WebElement.getAttribute("outerHTML")时,只会返回当前元素自身及其内部子节点的HTML字符串,不会传输整个页面的DOM数据,网络IO和解析开销远低于拉取全量pageSource,在复杂页面场景下性能提升非常明显。
改造后代码
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import java.util.List; public Elements getElementsByTag(final String tag) { // 直接通过Selenium定位目标标签,无全量页面拉取开销 List<WebElement> targetWebElements = webDriver.findElements(By.tagName(tag)); Elements result = new Elements(); for (WebElement webElement : targetWebElements) { // 仅提取单个目标元素的完整HTML片段 String elementOuterHtml = webElement.getAttribute("outerHTML"); // 解析HTML片段,避免Jsoup自动补全html/body等冗余标签 Document fragmentDoc = Jsoup.parseBodyFragment(elementOuterHtml); Element parsedJsoupElement = fragmentDoc.body().child(0); result.add(parsedJsoupElement); } return result; }
注意事项
- 该方案返回的
Elements对象和原有全量解析返回的对象用法完全一致,上层业务代码不需要做任何适配 - 如果需要使用Jsoup的复杂选择器做二次筛选,可以先用Selenium定位到范围更小的公共父节点,提取父节点的
outerHTML解析后再执行Jsoup选择器查询,兼顾性能和灵活性 - 必须提取
outerHTML属性而非innerHTML,否则会丢失当前定位元素本身的标签和属性,导致解析结果不符合预期 - 若需要按id、class、xpath等其他规则定位元素,只需要替换
findElements方法中的By定位条件即可,整体逻辑通用
内容的提问来源于stack exchange,提问作者user17953271
相关产品推荐
相关产品推荐

