3

Web サイト (より正確にはブラウザー ゲーム) とやり取りし、さまざまなページから情報を取得して GUI に出力する小さなプログラムを作成しようとしています。

問題なく印刷でき、問題なくログインでき、サイトをナビゲートできます。しかし、必要なデータを取得しようとすると (for-each ループを使用して行われます)、セレンは「要素が古いようです」というエラーをスローし続け、アプリケーションを終了します。

最初の惑星からデータを取得できましたが、それで終わりです。コード スニペットは次のとおりです。

public void getResources()
    {
        List<WebElement> planets = driver.findElements(By.className("smallplanet"));
        String name;
        int metal;
        int crystal;
        int deuterium;
        int energy;
        boolean firstPlanet = true;

        for(WebElement planet : planets)
        {       
            if(!firstPlanet)
            {
                WebElement tag = planet.findElement(By.tagName("a"));
                tag.click();
            } else
            {
                firstPlanet = false;
            }

            name = planet.findElement(By.className("planet-name")).getText();
            System.out.println(name);
            metal = Integer.parseInt(driver.findElement(By.id("resources_metal")).getText().replace(".", ""));
            crystal = Integer.parseInt(driver.findElement(By.id("resources_crystal")).getText().replace(".", ""));
            deuterium = Integer.parseInt(driver.findElement(By.id("resources_deuterium")).getText().replace(".", ""));
            energy = Integer.parseInt(driver.findElement(By.id("resources_energy")).getText().replace(".", ""));        

            resources.add(new ResourceLine(name, metal, crystal, deuterium, energy));
        }
    }

これはエラーです:

Element appears to be stale. Did you navigate away from the page that contained it?  And is the current window focussed the same as the one holding this element?
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_03'
Driver info: driver.version: HtmlUnitDriver

セレンがページをロードするのに十分な時間が与えられていないことが原因である可能性があると思いましたか? しかし、ページのダウンロードが完了するのを待っている間、セレンが EDT を停止させたと思いましたか? 私のUIは今のところ同じスレッドで実行されており、セレンがページの読み込みを完了するまで更新されないため、ログイン中にこれが行われることはわかっています。

いずれにせよThread.sleep()、50 から 500 の間でさまざまな長さの driver.wait を使用してみましたが、どちらも効果がないようです。

(注: HtmlUnitDriver の JavaScript を有効にしました)

編集:私はもう少しデバッグしてきましたが、セレンがページをロードするのに十分な時間が与えられていないためではないことを確認できます. プログラムは新しいページがロードされるのを待ちますが、何らかの奇妙な理由でまだその例外をスローします...

別の編集:

例外がスローされる限り、同じ try-catch ブロックを実行し続ける while ループで各 findElement ステートメントをラップしました。しかし、それは単に同じ古い要素の例外をスローし続ける無限ループです。

また、ページが実際に「自動更新」であることを付け加えたいと思うかもしれません. のように、取得しようとしている値は 500 ミリ秒ごとに更新されます。

4

1 に答える 1

5

StaleElementReferenceException が発生しています。これは通常、最初に WebElement を見つけてから、

  • ページをリロードしたか、別のページに移動してから戻った、または
  • Selenium でいくつかのアクションを実行した結果、DOM が変更されました

それでもあなたはその要素と対話しようとしました。あなたの場合、後者が問題のようです。tag.click()あなたはあなたのコードで実行しています。何をするのかはわかりませんが、何らかのデータが表示されると思いますか? これにより DOM が変更されるため、クリックする前に見つけた要素を参照できなくなります。tag.click() を呼び出した後は、毎回惑星のリストを調べる必要があるでしょう。(エラーが発生した行を書いていないので、これは私の推測です)

WebElement planet;
int size = driver.findElements(By.className("smallplanet")).size();
for(int i=0; i < size; i++)
{           
    if(!firstPlanet)
    {
        planet = driver.findElements(By.className("smallplanet")).get(i);
        WebElement tag = planet.findElement(By.tagName("a"));
        tag.click();
        planet = driver.findElements(By.className("smallplanet")).get(i);

    } else
    {
        firstPlanet = false;
        planet = driver.findElements(By.className("smallplanet")).get(i);
    }
    //rest of the code...
}
于 2013-08-31T20:47:38.800 に答える