为我调用WebEngine对象上的WebEngine()方法只返回从服务器检索的源,而不执行JavaScript (仍然有元素)。如果你在Chrome中使用“查看源代码”,你会看到这种源代码。如何在已经运行JavaScript的情况下检索解释的源?
public Browser() {
WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
webEngine.load("*******************************");
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
Document doc = webEngine.getDocument();
printDocument(doc);
}
}
});
}发布于 2015-03-09 15:54:27
您面临的问题是:在运行LoadWorker之前,JavaScript的状态设置为SUCCEEDED。JavaScript 实际上运行(如@James的答复中所示),但是在完成时没有回调信号。AFAIK,没有可靠的方法来检测WebEngine何时执行JS。
作为一种解决方法,您可以在状态更改为“成功”之后播放一个PauseTransition,它可以被滥用来充当JavaFX线程上的sleep (JS是在加载文档的后台线程中执行的,因此JS不会暂停)。但是,休眠(等待JS完成)本质上违反了JavaFX的核心原则从不使用来阻止UI线程。最重要的是,等待一段时间并不能保证JS是在该时间段过去之前执行的。
我也面临过同样的问题,我还没有找到一个合适的解决方案。如果你知道的话请告诉我!
发布于 2014-10-26 01:28:09
这对我来说就像预期的一样。在本例中,div包含一个文本节点,文本由Javascript函数设置:
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class WebViewOnLoadExample extends Application {
@Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
webView.getEngine()
.getLoadWorker()
.stateProperty()
.addListener((obs, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
Document doc = webView.getEngine().getDocument();
showNodeContent(doc, 0);
}
});
BorderPane root = new BorderPane(webView);
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
webView.getEngine().loadContent("<html>"
+"<head><script>"
+"function setText() {"
+" document.getElementById(\"target\").appendChild(document.createTextNode(\"Hello World\"));"
+"}"
+"</script></head>"
+"<body onload='setText()'>"
+"<div id='target'></div></body></html>");
}
private void showNodeContent(Node n, int depth) {
for (int i=0; i<depth; i++) {
System.out.print(" ");
}
System.out.println(n.getNodeName()+":"+n.getNodeValue());
NodeList children = n.getChildNodes() ;
for (int i=0; i<children.getLength(); i++) {
showNodeContent(children.item(i), depth+1);
}
}
public static void main(String[] args) {
launch(args);
}
}发布于 2014-10-25 13:57:58
我不确定我是否正确地回答了您的问题,但是如果您正在寻找一种方法去打印您正在加载的web的可见内容,从DocumentElement获取Document将允许您深入了解它的结构并过滤所需的内容。
此方法将打印所需标记的内容:
private void printElement(Element el, int level){
NodeList childNodes = el.getChildNodes();
for(int j=0; j<level; j++) System.out.print("-");
System.out.print("tag: "+el.getNodeName());
if(el.getNodeName().equals("A")){
System.out.print(", content: "+el.getTextContent());
}
System.out.println("");
for(int i=0; i<childNodes.getLength(); i++){
Node item = childNodes.item(i);
if(item instanceof Element){
printElement((Element)item, level++);
}
}
}因此,一旦加载了URL,只需调用它:
if(newState==State.SUCCEEDED){
Document doc = webEngine.getDocument();
Element el = doc.getDocumentElement();
printElement(el,0);
}这将打印所有DOM标记及其缩进级别,对于指定的标记,它也将打印内容。在这种情况下,使用标签"A“将打印所有链接的内容。
我不确定这会不会有帮助。否则请澄清你的问题。
https://stackoverflow.com/questions/26562380
复制相似问题