2

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 クラスを作成するという提案を受けました。次に、この問題を回避するために、関連するメソッドをオーバーライドします。

再度、感謝します。

4

1 に答える 1