在JavaFX2中使用WebEngine
时,我注意到它有时会卡住。假设我正在创建一个只在页面上找到超链接的爬虫,然后访问它们以递归方式执行相同操作,跟踪我们访问过哪些链接以及哪些已经在边界上。在运行我的代码时,执行有时会在任意时刻挂起。
我已经以workDoneProperty
和exceptionProperty
的听众形式向我的项目添加了一些调试代码,并打印了loadWorker
stateProperty
的每个转换。然后我注意到有时引擎会停止中间加载一个URL(状态卡在RUNNING
中,并且不再有workDone
个更新。我假设这是因为超时或其他什么,但我已经停止等待,看看它是否确实在5分钟后超时。
exceptionProperty
似乎没有生成任何事件,webEngine
也没有转换为FAILED
或CANCELLED
,它只是停止了。我想知道这是否可能是图书馆中的竞争条件,或者可能是我缺少的东西......有没有人遇到过这个谁知道如何解决这个问题?对我的应用程序而言,引擎不仅仅是随机停止......这一点非常重要......
编辑:从我的控制台添加输出:
Work done: -1
Engine Load Worker transitioning into state: READY
Work done: 0
Engine Load Worker transitioning into state: SCHEDULED
Engine Load Worker transitioning into state: RUNNING
Work done: 21
Work done: 24
Work done: 24
Work done: 57
Work done: 72
BUILD STOPPED (total time: 9 minutes 32 seconds)
答案 0 :(得分:3)
我遇到了同样的问题。 好像它发生在我在方法中创建了一个本地“WebView”实例而没有保留对它的硬引用时(因此在方法调用结束后 - 它可能是GC编辑的。)
我通过为我的WebView实例使用静态变量来修复问题(我正在JAVAFX线程中初始化 - 否则我得到一个异常)
private static WebView webview;
public static void someMethod() {
try {
if (webview == null){
webview = new WebView();
}
WebEngine webEngine = webview.getEngine();
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
public void changed(ObservableValue ov, State oldState, State newState) {
System.out.println("newState = " + newState);
if (newState == State.SUCCEEDED) {
System.out.println(webEngine.getLocation());
}
}
});
webEngine.load("http://javafx.com");
} catch (Exception ex) {
System.err.print("error " + ex.getMessage());
ex.printStackTrace();
}
}
答案 1 :(得分:0)
当您尝试两次加载同一站点时,WebEngine仍然处于“运行”状态。 解决方案是在每页空白页之后/之前加载。除非你已经在空白页面上。
我不建议使用JAvaFX WebEngine编写爬虫。是严重的错误。 (我知道,我是为大学项目而做的)
此外,如果您同时使用加载页面,请使用AtomicReference。
已编写的WebCrawler的参考:https://github.com/llde/crawly