Selenium ライブラリを使用して Java で開発されたページ クローラーがあります。クローラーは、ポップアップ ウィンドウに HTML として表示される Javascript 3 アプリケーションを介して起動する Web サイトを通過します。
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 が読み込まれます。これは一見、際限なく継続的に更新されます。
以下は、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)」が原因でメモリがすぐにいっぱいになるわけではなく、再試行する前に 3 分間待機する必要があります。
この問題を回避する方法について何か提案はありますか? 元のクラスを拡張する 2 つの新しい HtmlUnitDriver クラスと WebClient クラスを作成するという提案を受けました。次に、この問題を回避するために、関連するメソッドをオーバーライドします。
再度、感謝します。