Selenyum'da sayfa yüklenmesini bekleyin


Yanıtlar:


138

Sayfa yüklenenleri aşağıdaki kodu kullanarak da kontrol edebilirsiniz

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

 wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

22
Böyle bir şeyin inşa edileceğini düşünürsünüz. Sayfa yüklemelerini beklemek web'de oldukça yaygın bir şeydir.
PRMan

19
bu gerçekten her zaman işe yarıyor mu? Belki kodunuzda bir şey eksik ama dom'un hazır durumda olmasını bekliyorsunuz. Ancak, kodunuz çok hızlı yürütüldüğünde, önceki sayfanın henüz kaldırılmamış olabileceğini ve hala eski sayfada olsanız bile doğru döneceğini unutmayın. Yapmanız gereken, geçerli sayfanın kaldırılmasını bekleyin ve ardından yukarıdaki kodunuzu arayın. Sayfa kaldırmayı tespit etmenin bir yolu, geçerli sayfada bir webelement almak ve eski haline gelene kadar beklemektir. obeythetestinggoat.com/…
George

6
FYI - Yukarıdakiler bile sayfanın tamamlandığını garanti etmiyor - sadece dom'un hazır olduğunu. Herhangi bir dojo / jquery hala dinamik olarak sayfadaki öğeleri oluşturuyor olabilir, bu nedenle onlarla etkileşime geçmeden önce dinamik öğeleri beklemeniz gerekebilir.
George

3
Bu yöntemin yalnızca DOM'yi kontrol ettiğini unutmayın. Ajax veya AngularJS kullanıyorsanız, belge tarafından algılanamayan bazı eşzamansız çağrılar olacağından bu çalışmaz.
Homewrecker

3
Bu C # kodudur. Bu Java ile çalışmaz ve soru sorulduğunda Java .
Kingamere

89

Sınıfı kullan WebDriverWait

Ayrıca bakınız buraya

Bazı öğeleri göstermeyi bekleyebilirsiniz. C # gibi bir şey:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));

Bu harika çalıştı. Bu sorunu çözmek için çok güzel ve modern bir yol.
CrazyDart

3
@ EmmanuelAngelo.R TimeSpan bir .Net veri yapısıdır.
rjzii

12
sayfada hangi öğenin olacağını bilmezsem ne olur?
JustGoscha

3
Bu, tüm sayfa için değil, belirli bir öğenin yüklenmesini beklemeye çalışır.
xyz

1
Bu, bir öğenin tam olarak yükleneceğini ve hiçbirinin soruyu cevaplamadığını garanti etmez. Herkes buna nasıl oy verebilir?
Boris D. Teoharov

36

Sürücünün örtük beklemesini ayarlarsanız, findElementyöntemi yüklenen sayfada olmasını beklediğiniz bir öğede çağırırsanız , WebDriver öğeyi bulana veya zaman aşımı değerine ulaşıncaya kadar bu öğe için yoklama yapar.

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Kaynak: implicit-waits


3
Sayfa yüklemesini beklemede yardımcı olmaz.
xyz

Bu, istisnayı yükseltmeden önce 10 saniye boyunca bir şey deneyeceği anlamına gelir. bu yüzden 10 saniye gecikme alacağından emin olamaz.
gökdelen

1
@xyz - neden yardımcı olmuyor?
MasterJoe2

@ testerjoe2 belirli bir öğe bulunana kadar bekler, soru sayfa yüklenmesini nasıl bekleyeceğinizle ilgilidir.
xyz

35

Genel olarak, Selenium 2.0 ile web sürücüsünün kontrolü yalnızca sayfanın yüklendiğini belirledikten sonra arama koduna döndürmesi gerekir. Başlamazsa waitforelemement, hangi çağrıyı findelementbulunana veya zaman aşımına uğrayacak şekilde çevirir (zaman aşımı ayarlanabilir).


2
Paul'ün cevabına ekleme. Lütfen bunu da kontrol edin stackoverflow.com/questions/5858743/… .
9ikhan

27
Ne yazık ki, Selenium 2 her durumda bir sayfanın yüklenmesini beklemez. Örneğin, WebElement: click () beklemez ve bu ilgili Javadoc'ta açıkça söylenir. Ancak, yüklenecek yeni bir sayfayı nasıl kontrol edebileceğimi söylemiyorlar. If click() causes a new page to be loaded via an event or is done by sending a native event (which is a common case on Firefox, IE on Windows) then the method will not wait for it to be loaded and the caller should verify that a new page has been loaded.
Sebi

Gönderen doc yük tamamlanana kadar yöntem engeller ..ve ...
xyz

2
@Karna: Evet, teoride her zaman olmalı ve pratikte çoğu zaman yaptı. Selenyum'u o sırada kullanmak, sayfanın yüklenmeyi bitirdiğini düşündüğü zamanların olduğunu vurguladı. Son zamanlarda selenyum kullanmadım, bu durum hala geçerli olabilir veya olmayabilir.
Paul Hadfield

3
Kabul ediyorum: özellikle internet explorer sürücüsü buggy ve bir sayfa hala yükleniyor olsa bile bazı durumlarda hemen kontrolü döndürür. Benim durumum, kullanarak bir bekleme ekledi JavascriptExecutor, document.readyState "tam" olmasını bekliyorum. Selenyumdan tarayıcıya gidiş dönüş nedeniyle yarış durumu hafifletildi sanırım ve bu "her zaman" benim için çalışıyor. Bir sayfanın yüklenmesini beklediğimde "click ()" den sonra, readystate için açıkça (WebDriverWait kullanarak) beklerim. ]
dmansfield

22

Ruby uygulaması:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}

17
Python eşdeğeri: WebDriverWait .until (sürücü, 10) (lambda d: d.execute_script () == 'tam' document.readyState dön ')
yangını

2
Python yukarıdaki kodu kullanın, ancak bu satırı unutmayın .. | selenium.webdriver.support.ui
adresinden

Sayfa tam olarak yüklenmediğinde bir öğeyi tıklamakta sorun yaşadım. Python'da time.sleep (30) denedim. İşe yaradı. Her zaman maksimum 30 saniye bekleyecektir. Daha sonra aşağıdaki kodu denedim ve şimdi daha verimli, daha hızlı. WebDriverWait (sürücü, 10) .until (lambda d: driver.find_element_by_xpath ("// div [. = 'Administration']"). Tıklayın ())
Riaz Ladhani 11:15

20

System.outÇizgiyi kaldırabilirsiniz . Hata ayıklama amacıyla eklenir.

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}

Bu ipuçları için teşekkürler. SeleniumHelper'ım içine ekliyorum; bakınız javabox
boly38 20:14

17

Tüm bu çözümler belirli durumlar için uygundur, ancak birkaç olası sorundan en az birini yaşarlar:

  1. Yeterince genel değildirler - önceden, belirli bir koşulun gideceğiniz sayfa için geçerli olacağını bilmenizi isterler (örneğin, bazı öğeler görüntülenir)

  2. Bunlar, hem eski sayfada hem de yeni sayfada mevcut olan bir öğeyi kullandığınız bir yarış koşullarına açıktır.

İşte bu sorunu (Python'da) önleyen genel bir çözüm denemem:

İlk olarak, genel bir "bekle" fonksiyonu (isterseniz bir WebDriverWait kullanın, onları çirkin buluyorum):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Daha sonra çözüm, selenyumun, üst düzey <html>öğe de dahil olmak üzere bir sayfadaki tüm öğeler için (dahili) bir kimlik numarası kaydetmesine dayanır . Bir sayfa yenilendiğinde veya yüklendiğinde, yeni bir kimliğe sahip yeni bir html öğesi alır.

Örneğin, "bağlantım" metnine sahip bir bağlantıyı tıklamak istediğinizi varsayarsak, örneğin:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

Daha fazla Pythonic, yeniden kullanılabilir, genel yardımcı için bir içerik yöneticisi yapabilirsiniz:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

Ve sonra hemen hemen tüm selenyum etkileşimlerinde kullanabilirsiniz:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

Sanırım bu kurşun geçirmez! Ne düşünüyorsun?

Bu konuda bir blog yazısında daha fazla bilgi


Çözümünüzü uygulayan java kodunu daha ayrıntılı olarak aramadan önce web sayfanızı okudum. Şimdiye kadar hiçbir şey ...
andrew lorien

11

Ayrıca, ExpectedConditionsherhangi bir işlem yapmadan önce bir öğenin web sayfasında görünmesini açıkça beklemek için class: öğesini kullanabilirsiniz.

ExpectedConditionsBir öğenin görünür olup olmadığını belirlemek için sınıfı kullanabilirsiniz :

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));

ExpectedConditions class JavadocKontrol edebileceğiniz tüm koşulların listesi için bkz .


11

İmran'ın yanıtı Java 7 için yeniden düzenlendi:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });

10

Bu WebDriver'ın ciddi bir kısıtlaması gibi görünüyor. Bir öğeyi beklemek, sayfanın yüklenmekte olduğu anlamına gelmez, özellikle DOM tamamen oluşturulabilir (zaten devlet), böylece JS hala yürütülüyor ve CSS ve görüntüler hala yükleniyor.

Her şey başlatıldıktan sonra onload olay üzerine bir JS değişkeni ayarlamak ve Selenium bu JS değişkeni beklemek ve beklemek en basit çözüm olduğuna inanıyorum.


Siteyi değiştirmek sizin için basitse!
reinierpost

Evet, jQuery.js dosyasını çalıştırmak için bir JavascriptExecutor kullanın ve sonra jQuery yükleme olaylarına erişiminiz olur. Ancak bunun gerekli olduğu nadir bir durumdur. Standart Webdriver, uygun beklemelerin% 98'ini yapacak kadar güce sahiptir.
djangofan

@ djangofan bunun bir örnek görmek harika olurdu ... Ben bir ön uç adam JavascriptExecutor nerede veya nasıl kullanılır emin değilim.
BradGreens

@BradGreens - Tamam, projeme buradan bakın: github.com/djangofan/jquery-growl-selenium-example . Bu örneği bitirmek için bant genişliğiniz varsa, jQuery iyi çalışmasına rağmen jGrowl'un bu test projesinde çalışmasını sağlayamadım.
djangofan

1
@BradGreens djangofan'ın yorumuna ek olarak cevabımı da burada görebilirsiniz: stackoverflow.com/a/24638792/730326
jmathew

9

Belirli bir öğenin yüklenmesini beklemek istiyorsanız, isDisplayed()yöntemi aşağıdakiler üzerinde kullanabilirsiniz RenderedWebElement:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));

    // If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}

( 5 Dakikalık Başlangıç ​​Kılavuzu'ndan örnek )


4
Bir yıl sonra (şu anki Selenyum sürüm 2.23.1), API'da hiç yok RenderedWebElement. Ancak, isDisplayed()yöntem artık doğrudan kullanılabilir WebElement.
Petr Janeček

1
Yoklama kaçınılmaz olduğunda korkunçtur.
reinierpost

8

Açıkça bekleyin ya da koşullu bekleyin, bu koşul verilene kadar bekleyin.

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

Bu, her web öğesi için 60 saniye bekleyecektir.

Sayfadaki her öğenin verilen süreye kadar beklemesini dolaylı olarak kullanın.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

Bu, her web öğesi için 60 saniye bekleyecektir.


5

Belirli bir zamana kadar sayfadaki her öğenin beklemesini dolaylı olarak kullanın.

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

bu sayfadaki her öğe için 30 saniye bekleyin.

Başka bir bekleme, belirli bir duruma gelene kadar bu bekleyişte açıkça beklemek veya koşullu beklemedir.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

İd'de, sayfa yüklenir yüklenmez sayfada farklı şekilde görüntülenen statik öğe kimliği verin.


4

Yüklemeyi beklediğiniz sayfada genellikle hangi öğeyle etkileşime gireceğinizi bildiğiniz için tahminlerin ilk seçenek olmadığına şaşırıyorum. Benim yaklaşımım her zaman waitForElementByID(String id),waitForElemetVisibleByClass(String className) ve sonra bunları beklediğim sayfa yükü veya sayfa içeriği değişikliği için ihtiyaç duyduğum her yerde kullanmak ve yeniden kullanmak olmuştur.

Örneğin,

Test sınıfımda:

driverWait.until(textIsPresent("expectedText");

Test sınıfı üstümde:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}

Bu çok fazla gibi görünse de, sizin için tekrar tekrar kontrol etmeye özen gösterir ve zaman aşımına uğramadan önce nihai bekleme süresi ile birlikte ne sıklıkta kontrol edilebileceğine dair aralık ayarlanabilir. Ayrıca, bu yöntemleri yeniden kullanacaksınız.

Bu örnekte, ve sınıfı üst WebDriver driverve WebDriverWait driverWait.

Umarım bu yardımcı olur.


Bu bana yardımcı oluyor! Bu mükemmel örnek için teşekkürler. SeleniumHelper'ım içine ekliyorum; bakınız javabox
boly38 20:14

4

WebDriver için Java bağlarını kullanırken sayfa yüklemelerini beklemenin en iyi yolu, PageFactory ile Sayfa Nesnesi tasarım desenini kullanmaktır. Bu, AjaxElementLocatorFactoryhangi öğeyi koyacağınızı tüm öğeleriniz için küresel bir bekleme görevi görmenizi sağlar. Drop-box veya karmaşık javascript geçişleri gibi öğeler üzerinde sınırlamalar vardır, ancak gerekli kod miktarını önemli ölçüde azaltacak ve test sürelerini hızlandıracaktır. Bu blog yazısında iyi bir örnek bulunabilir. Core Java'nın temel olarak anlaşıldığı varsayılmaktadır.

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html


4

NodeJS Çözümü:

In Nodejs Eğer vaat yoluyla alabilirsiniz ...

Bu kodu yazarsanız, bu sayfaya ulaştığınızda sayfanın tamamen yüklendiğinden emin olabilirsiniz ...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Bu kodu yazarsanız, navigasyon yaparsınız ve selenyum 3 saniye bekleyecektir ...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

Selenyum belgelerinden:

this.get (url) → Sonradan

Belirtilen URL'ye gitmek için bir komut zamanlar.

Belge yüklemesi bittiğinde çözülecek bir söz verir .

Selenyum Belgeleri (Nodejs)


4

Şu anda en çok oylanan cevabın Java 8 sürümü :

WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));

myDriverBir WebDrivernesne nerede (daha önce beyan edilmiş).

Not : Bu yöntemin ( document.readyState) yalnızca DOM'yi kontrol ettiğini unutmayın.


4

Komut dosyanızdaki fonksiyonun altında arayın, sayfa javascript kullanılarak yüklenene kadar bekler

public static boolean isloadComplete(WebDriver driver)
{
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
            || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}


3
/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}

/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}

Belgenin yalnızca bir bölümünün değişmesi durumunda, belgeden bir öğeye geçiş yapabilirsiniz.

Bu teknik, sincebasic'in cevabından ilham aldı.


3

SelenyumWaiter :

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

Ve onu kullanmak için :

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}

3

Sayfanın yüklenmesi 20 saniyeden uzun sürüyorsa, aşağıdaki örnekte pageeLoadTimeout zamanını ayarlamak için aşağıdaki mevcut yöntemi kullanabilirsiniz, ardından sayfanın yeniden yüklenmesi için bir istisna atar

 WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)

2

Herhangi bir işlem yapmadan önce bir öğenin web sayfasında görünmesini açıkça bekleyebilirsiniz (element.click () gibi)

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(new ExpectedCondition<WebElement>(){
        @Override
        public WebElement apply(WebDriver d) {
        return d.findElement(By.id("myDynamicElement"));
}});

Benzer bir senaryo için kullandığım bu ve iyi çalışıyor.


Bence sürücü.get onload işlevi kod kontrol kontrol önce bitirmek için bekler, sayfa ajax bir sürü sürece
goh

2

Benim basit yolum:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;

        while (System.currentTimeMillis() < end) {

            if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }

2

Gördüğüm en iyi yol, stalenessOf , eski sayfanın eski haline gelmesini beklemek için ExpectedCondition'ı .

Misal:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);

WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));

Eski HTML etiketinin eski hale gelmesi on saniye bekleyecek ve sonra gerçekleşmezse bir istisna atacaktır.


1
bir WebElement eski bataryanın yeni bir sayfanın yüklenmesinin gerektiği anlamına gelmez.
Corey Goldberg

Elbette, ancak eski sayfanın kaldırılması bitti demektir. Deneyimlerime göre, eski sayfanın ne zaman kaldırıldığını veya bir nedenle durduğunu bilmek de önemlidir.
forresthopkinsa

Tabii ki, tam boşaltma / yükleme işlemini elde etmek için tipik olarak diğer testlerle birlikte stalenessOf kullanıyorum.
forresthopkinsa

2

Düğüm + selenyum-webdriver kullanıyorum (hangi sürüm şimdi 3.5.0). bunun için ne yapıyorum:

var webdriver = require('selenium-webdriver'),
    driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
  return state === 'complete';
}))

2

Wait kullanabilirsiniz. selenyumda temel olarak 2 tip bekleme vardır

  • Örtülü bekleme
  • Açık bekleme

- Örtük bekleme

Bu çok basit, lütfen aşağıdaki sözdizimine bakın:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

- Açık bekle

Belirli bir koşul oluşana kadar bu bekleyişte açıkça bekleyin veya koşullu bekleyin.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

Gibi diğer özellikleri kullanabilirsiniz visblityOf(),visblityOfElement()



2

Benim durumumda, sayfa yükleme durumunu bilmek için aşağıdakileri kullandım. Bizim uygulama yükleme gif (ler) mevcuttur ve ben, ben komut dosyasında istenmeyen bekleme süresini ortadan kaldırmak için aşağıdaki gibi onları dinlerim.

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

Burada xpath, HTML DOM'deki gif'i bulur. Bundan sonra, eylem yöntemlerinizi de uygulayabilirsiniz Tıklayın.

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }

2

Dostum, tüm bu cevaplar çok fazla kod gerektiriyor. Bu oldukça yaygın olduğu için basit bir şey olmalı.

Neden sadece webdriver ve kontrol ile basit bir javascript enjekte değil. Bu benim web scraper sınıfımda kullandığım yöntem. JavaScript bilmeseniz bile javascript oldukça basittir.

    def js_get_page_state(self):        
    """
    Javascript for getting document.readyState
    :return: Pages state.

    More Info: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
    """
    ready_state = self.driver.execute_script('return document.readyState')
    if ready_state == 'loading':
        self.logger.info("Loading Page...")
    elif ready_state == 'interactive':
        self.logger.info("Page is interactive")
    elif ready_state == 'complete':
        self.logger.info("The page is fully loaded!")
    return ready_state

1

Bir tıklamadan sonra Selenyum'un sayfa yüklemesini beklemesi nasıl yapılır , aşağıdaki ilginç yaklaşımı sağlar:

  1. WebElementEski sayfadaki bir öğeye referans depolayın .
  2. Linke tıklayınız.
  3. Atılana WebElementkadar işlemleri çağırmaya devam edin StaleElementReferenceException.

Basit kod:

WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
    try
    {
        link.isDisplayed();
        return false;
    }
    catch (StaleElementReferenceException unused)
    {
        return true;
    }
});

İyi bir fikir! Ben başarılı bir sayfa yükleme, başarılı bir sayfa boşaltma (daha iyi bir terim eksikliği için) tersini kontrol ederek bu durumla başa çıkmak için hiç düşünmemiştim. Bunun en iyi seçenek olup olmadığı, StaleElementReferenceException öğesinin başarılı bir yükleme beklemekten daha az zaman alıp almadığına bağlıdır. Bununla birlikte, bunu yapmanın başka bir iyi yolu.
Joseph Orlando

4
Bu size geçerli sayfanın yüklü olup olmadığını söylemeyecek, son sayfanın (özellikle bir öğe) kaldırılıp kaldırılmadığını size söyleyecektir . Mevcut sayfanın yüklenmesini beklemeniz gerekecek. BTW, yukarıdaki kodunuzu değiştirebilirsiniz new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(element)).
JeffC
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.