-1

理解するのに長い時間がかかりましたが、それでも私はこれに苦労しています. Selenium webdriver を使用して JavaScript インジェクションを使用して、Web ページ上で動的に生成された要素にアクセスしようとしています。例えば:

 String hasclass = js.executeScript("return document.getElementById('additional-details').children[0].children[0].children["
                            + k + "].children[0].classList.contains(\"results-execs-name\")").toString();

Firefox コンソールでこのスクリプトを実行すると、問題なく動作します。ただし、この行は、webdriver で 10 回のうち 5 ~ 6 回実行すると例外をスローします (要素が物理的に存在していても)。

なぜそれが起こっているのですか?で、解決策は?ヒント/回答が役立つ場合は、必ず賛成します。

編集:

私はすでに Thread.sleep(500) を入れており、コード内で executeScript() が発生する前に 1000 秒も待機しています。それでも機能しません。

(部分的な)スタックトレースは次のとおりです。

org.openqa.selenium.WebDriverException: document.getElementById(...).children[0].children[0] is undefined
Command duration or timeout: 169 milliseconds
Build info: version: '2.39.0', revision: 'ff23eac', time: '2013-12-16 16:12:12'
System info: host: 'rahulserver-PC', ip: '121.245.92.68', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_17'
Session ID: 747d2095-09f3-48b9-a433-59c5e334d430
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=XP, databaseEnabled=true, cssSelectorsEnabled=true, javascriptEnabled=true, acceptSslCerts=true, handlesAlerts=true, browserName=firefox, webStorageEnabled=true, nativeEvents=false, rotatable=false, locationContextEnabled=true, applicationCacheEnabled=true, takesScreenshot=true, version=31.0}]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:193)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:554)
    at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:463)
    at Scraper.main(Scraper.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
4

3 に答える 3

1

動的に生成されたリストの場合、xPathを使用して要素を見つけるのが最善です。

より良い解決策として、要素が動的に生成されている場所を言う必要がありますか? テーブルul / liなどの内側に配置できます。

  1. まず、親要素、つまりテーブルまたはリスト アイテムへのxPathを見つけます。
  2. 次に、 loop を使用して要素の位置への動的 xPath を作成します。コード スニペットは次のとおりです。

    String xPath_1 = ".//li[@class='item drop-shadow tiny-shadow' and position()=";
    String xPath_2 = "]//div[@class='item-inner']//a";
    String finalxPath = xPath_1 + i + xPath_2;
    
  3. スレッド スリープを使用するのではなく、要素が存在するのを待機する fluentWait というメソッドを作成します。スレッドのスリープは信頼できず、テストが失敗する原因になります。また、fluentWait メソッドはNoSuchElementExceptionを無視します ( StateStateElementExceptionなどのリストにさらに追加できます)。コード スニペットは次のとおりです。

    public void fluentWait(final By by)
    {
        FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
               .withTimeout(60, TimeUnit.SECONDS)
               .pollingEvery(5, TimeUnit.SECONDS)
               .ignoring(NoSuchElementException.class);
           WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
             public WebElement apply(WebDriver driver) {
               return driver.findElement(by);
             }
           });
    }
    
  4. 次に、次のように動的に生成された xPath でこのメソッドを呼び出します。

    fluentWait(By.xpath(finalxPath ));
    

xPath について学習するには、次のチュートリアルを使用できます。これを試して、私に知らせてください。乾杯

于 2014-08-02T08:24:08.850 に答える