所以我发现如果你使用WebDriver获取页面源,你实际上得到了整个DOM的生成源(而不仅仅是加载页面的HTML源代码)。然后,您可以使用此String生成Jsoup文档。这很酷,因为在搜索元素时Jsoup比WebDriver快得多,它也有更好的API。
那么,无论如何将Jsoup元素转换为WebDriver WebElement?我在stackoverflow上看到另一篇关于使用方法从Jsoup文档生成xpath的帖子,但这不是我正在寻找的,因为WebDriver仍然需要解析页面并使用Xpath来查找元素,从而破坏了目的(除非你的porpuse纯粹使用Jsoup作为其卓越的Selector方法)。
我想尝试使用Jsoup为WebDriver找到WebElements的原因是因为在某些网站上,WebDriver非常慢(我为自动化数百个第三方网站的公司工作,我们无法控制这些网站)
答案 0 :(得分:2)
这里的交互式和非交互式工具之间似乎存在混淆。
WebDriver测试通常很慢(根据我的经验)由于不必要和防御性的等待和延迟,使用不正确理解的框架,并且通常由初级或外包开发人员编写 - 但从根本上也是因为WebDriver模仿真实用户的行为在真实浏览器上“实时”,并使用API(基于specification)和协议与浏览器应用进行通信。这是互动的。
(对HtmlUnit,PhantomJS等不太重要)
相比之下,Jsoup只是一个美化的HTTP客户端,具有额外的解析功能。它是非交互式的,最终可以处理快照数据字符串。我们预计它的特定用例会更快 。
显然两者都是某种类型的HTTP客户端,并且可以共享静态Web内容,这就是为什么WebDriver可以将数据传递给Jsoup进行处理(尽管我之前从未听说过这种用例)。
然而,Jsoup永远不会将其Element
之一(包含某些属性的Java快照对象)转换为WebDriver WebElement
,这更像是一个真实的“实时”代理。 Firefox或Chrome等程序中的交互式对象。 (再说一次,HtmlUnit,PhantomJS等等)。
因此,您需要确定交互性是否对您很重要。如果模仿真实用户至关重要,那么WebDriver必须使用真实的浏览器“驱动”这个过程。
如果不是,那么你可以考虑像HtmlUnit和(特别是)PhantomJS这样的无头浏览器,因为他们将能够以HTTP库和Jsoup不能的方式执行JavaScript并更新DOM。然后,您可以将输出传递给Jsoup等。
潜在地,如果您沿着PhantomJS路线走下去,您可以使用JavaScript API在那里进行所有解析。请参阅:Use PhantomJS to extract html and text等。
对于很多人而言,交互性并不重要,而且完全放弃WebDriver并依赖库来更快。
答案 1 :(得分:0)
我知道这个问题太老了,但是只要有人看到这个问题,就可以找到这个答案。这将从您的Jsoup元素返回一个xpath。我将其翻译成Java,但是我从中复制代码的原始来源是https://stackoverflow.com/a/48376038/13274510。
然后可以将xpath与WebDriver一起使用
编辑:代码现在可以使用
public static String jsoupToXpath(Element element) {
String xpath = "/";
List<String> components = new ArrayList<>();
Element child = element.tagName().isEmpty() ? element.parent() : element;
System.out.println(child.tag());
while (child.parent() != null){
Element parent = child.parent();
Elements siblings = parent.children();
String componentToAdd = null;
if (siblings.size() == 1) {
componentToAdd = child.tagName();
} else {
int x = 1;
for(Element sibling: siblings){
if (child.tagName().equals(sibling.tagName())){
if (child == sibling){
break;
} else {
x++;
}
}
}
componentToAdd = String.format("%s[%d]", child.tagName(), x);
}
components.add(componentToAdd);
child = parent;
}
List<String> reversedComponents = new ArrayList<>();
for (int i = components.size()-1; i > 0; i--){
reversedComponents.add(components.get(i));
}
xpath = xpath + String.join("/", reversedComponents);
return xpath;
}