我有一个使用 Selenium 库用 Java 开发的页面爬虫。爬虫通过一个网站,该网站通过 Javascript 3 应用程序启动,这些应用程序在弹出窗口中显示为 HTML。
爬虫在启动 2 个应用程序时没有问题,但在第 3 个应用程序中,爬虫永远冻结。
我使用的代码类似于
public void applicationSelect() {
...
//obtain url by parsing tag href attributed
...
this.driver = new HtmlUnitDriver(BrowserVersion.INTERNET_EXPLORER_8);
this.driver.seJavascriptEnabled(true);
this.driver.get(url); //the code does not execute after this point for the 3rd app
...
}
我还尝试通过以下代码单击 web 元素
public void applicationSelect() {
...
WebElement element = this.driver.findElementByLinkText("linkText");
element.click(); //the code does not execute after this point for the 3rd app
...
}
单击它会产生完全相同的结果。对于上面的代码,我确保我得到了正确的元素。
谁能告诉我我遇到的问题可能是什么?
在应用程序方面,我不能透露有关 html 代码的任何信息。我知道这使尝试解决问题变得更加困难,为此我提前道歉。
=== 2013-04-10 更新 ===
因此,我将源代码添加到了我的爬虫中,并在 this.driver.get(url) 中看到了它被卡住的位置。
基本上,驱动程序会在无限刷新循环中丢失。在由 HtmlUnitDriver 实例化的 WebClient 对象中,加载了一个 HtmlPage,该 HtmlPage 不断刷新,似乎没有尽头。
这是来自 com.gargoylesoftware.htmlunit 的 WaitingRefreshHandler 的代码:
public void handleRefresh(final Page page, final URL url, final int requestedWait) throws IOException {
int seconds = requestedWait;
if (seconds > maxwait_ && maxwait_ > 0) {
seconds = maxwait_;
}
try {
Thread.sleep(seconds * 1000);
}
catch (final InterruptedException e) {
/* This can happen when the refresh is happening from a navigation that started
* from a setTimeout or setInterval. The navigation will cause all threads to get
* interrupted, including the current thread in this case. It should be safe to
* ignore it since this is the thread now doing the navigation. Eventually we should
* refactor to force all navigation to happen back on the main thread.
*/
if (LOG.isDebugEnabled()) {
LOG.debug("Waiting thread was interrupted. Ignoring interruption to continue navigation.");
}
}
final WebWindow window = page.getEnclosingWindow();
if (window == null) {
return;
}
final WebClient client = window.getWebClient();
client.getPage(window, new WebRequest(url));
}
指令“client.getPage(window, new WebRequest(url))”再次调用 WebClient 来重新加载页面,只是再次调用这个相同的刷新方法。这似乎无限地进行,仅因为“Thread.sleep(seconds * 1000)”而没有快速填满内存,这会在重试之前强制等待 3m。
有没有人对我如何解决这个问题有任何建议?我建议创建 2 个新的 HtmlUnitDriver 和 WebClient 类来扩展原始类。然后重写相关方法以避免这个问题。
再次感谢。