Soru Selenium'da sayfa yüklemesini bekle


Nasıl yapıyorsun Selenyum 2.0 sayfanın yüklenmesini bekleyin.


193
2018-05-03 10:59


Menşei


Sadece benim için Paul Cevap doğru görünüyor, belli bir unsuru beklemek konusunda son derece oy veren cevapların çoğu. - xyz


Cevaplar:


Aşağıdaki kodu kullanarak önceden ayrılmış olarak 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"));

116
2017-07-06 05:18



Bu daha doğru bir yaklaşım. - Benjamin Gruenbaum
Böyle bir şeyin inşa edileceğini düşünürdünüz. Sayfa yüklemelerini beklemek, web'de oldukça yaygın bir şeydir. - PRMan
Bu gerçekten her zaman çalışır mı? Belki de kodunuzdan bir şey özledim ama domın hazır durumda olmasını bekliyorsunuz. Ancak, kodunuz çok hızlı bir şekilde yürütüldüğünde, önceki sayfanın henüz kaldırılmayacağını ve eski sayfada olmanıza rağmen gerçeğin geri döneceğini düşünün. Yapmanız gereken şey, mevcut sayfanın yüklenmesini beklemek ve ardından yukarıdaki kodu çağırmaktır. Sayfa boşaltmayı tespit etmenin bir yolu, geçerli sayfada bir web bağlantısı elde etmektir ve eski haline gelinceye kadar beklemektir. obeythetestinggoat.com/... - George
FYI - Yukarıdakiler bile, sayfanın tamamlandığını garanti etmez - sadece dom hazırdır. Herhangi bir dojo / jquery hala sayfadaki öğeleri dinamik olarak oluşturabilir, bu yüzden onlarla etkileşim kurmadan önce dinamik öğeleri beklemeniz gerekebilir. - George
Bu yöntemin yalnızca DOM'yi kontrol ettiğini unutmayın. Ajax veya AngularJS kullanırsanız, bu çalışmayacaktır çünkü document.readyState tarafından algılanamayan bazı zaman uyumsuz çağrılar olacaktır. - Homewrecker


Kullanım sınıfı WebDriverWait

Ayrıca bkz. İşte

Bazı unsurları 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"));

83
2017-10-18 18:16



Bu harika çalıştı. Sorunu çözmek için çok güzel ve modern bir yol. - CrazyDart
@ EmmanuelAngelo.R Zaman aralığı bir Net veri yapısıdır. - rjzii
sayfada hangi elemanın olacağını bilmiyorsam ne olur? - JustGoscha
Bu, tüm sayfa için değil belirli bir öğenin yüklenmesini beklemek için çalışacaktır. - xyz
Bu, bir elemanın tamamen yükleneceğini garanti etmez, ne de soruya cevap verir. Kimse buna nasıl karşılık verebilir? - Boris D. Teoharov


Sürücünün örtülü bekleyişini ayarlarsanız, findElement Yüklenen sayfada bulunmayı beklediğiniz bir öğedeki yöntemde, WebDriver öğesi öğeyi bulana veya zaman aşımı değerine ulaşana kadar bu öğe için yoklar.

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

kaynak: örtük-bekler


31
2017-11-29 15:50



Sayfa yüklemesini beklemede yardımcı olmaz. - xyz
Bu, istisna artırmadan önce 10 saniye boyunca bir şey deneyeceği anlamına gelir. bu yüzden 10 saniye gecikme alacağından emin olamaz. - skysign
@xyz - neden yardım etmiyor? - testerjoe2
@ testerjoe2, belirli eleman bulunana kadar bekler, soru, sayfa yüklemesini beklemekle ilgilidir. - xyz


Genel olarak, Selenium 2.0 ile web sürücüsü, sayfanın yüklendiğini belirledikten sonra sadece çağrı kodunu arama kontrolüne döndürmelidir. Yoksa, arayabilirsin waitforelemementhangi döngüleri çağırıyor findelement bulunana veya zaman aşımına uğradığında (zaman aşımı ayarlanabilir).


30
2018-05-03 22:27



Paul'un cevabına ekleme. Lütfen bunu da kontrol et stackoverflow.com/questions/5858743/.... - 9ikhan
Ne yazık ki, Selenium 2 bir sayfanın yüklenmesi için her durumda beklemez. Örneğin, WebElement: click () beklemez ve bu açıkça Javadoc'ta aittir. 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
itibaren doktor  ..ve yükleme tamamlanıncaya kadar yöntem bloke olacak ... - xyz
@Karna: Evet, teoride her zaman ve pratikte çoğu zaman yapmalıydı. O zamanlar Selenium'u kullanmak, sayfanın yükleme işlemini tamamladığını düşündüğü zamanlar olduğunu, ancak bunu yapmadığını vurguladı. Son zamanlarda çok selenyum kullanmadım, bu durum hala olabilir veya olmayabilir. - Paul Hadfield
Katılıyorum: ö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 ekledim JavascriptExecutor , "complete" olmak için document.readyState öğesini bekliyor. Selenyumdan tarayıcıya yapılan gidişattan dolayı, yarış durumu hafifletiliyor 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


Ruby uygulaması:

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

21
2018-02-15 18:56



Python eşdeğeri: WebDriverWait (sürücü, 10) .sayısı (lambda d: d.execute_script ('return document.readyState') == 'complete') - blaze
Python yukarıdaki kodu kullan ama bu satırı unutma .. | selenium.webdriver.support.ui adresinden içe aktarma WebDriverWait - t3dodson
Sayfa tam olarak yüklenmediğinde bir öğeye tıklandığında bir sorun yaşadım. Python'da time.sleep çalıştım (30). İşe yaradı. Her zaman azami 30 saniye bekler. Daha sonra aşağıdaki kodu denedim ve şimdi daha hızlı, daha hızlı. WebDriverWait (driver, 10) .until (lambda d: driver.find_element_by_xpath ("// div [. = 'Administration']") 'ı tıklatın ()) - Riaz Ladhani


Kaldırabilirsiniz System.out hat. 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");
        }
    });
}

13
2018-04-02 14:28



Bu ipuçları için teşekkürler. SeleniumHelper'ma ekliyorum; bakınız javabox - boly38


Sınıfı da kullanabilirsiniz: ExpectedConditions Herhangi bir eylemde bulunmadan önce bir öğenin web sayfasında görünmesini beklemek için

Kullanabilirsiniz ExpectedConditions Bir öğenin görünür olup olmadığını belirlemek için sınıf:

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

Görmek ExpectedConditions class Javadoc kontrol edebileceğiniz tüm koşulların listesi için.


11
2018-02-24 11:58





Tüm bu çözümler belirli durumlar için uygundur, ancak olası birkaç problemden en az birinden muzdariptirler:

  1. Bunlar yeterince genel değiller - bilmeniz gerekenler, önceden belli bir koşulun, gittiğiniz sayfa için geçerli olacağı (örneğin, bazı elemanlar gösterilecek)

  2. Eski sayfada ve yeni sayfada bulunan bir öğeyi kullandığınız bir yarış durumuna açıktır.

İşte bu problemden kaçınan genel bir çözüm denemem (Python'da):

İlk olarak, genel bir "bekleme" 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__))

Ardından çözüm, selenyumun bir sayfadaki tüm öğeler için (iç) bir kimlik numarasını kaydettiği gerçeğine dayanır. <html> öğesi. Bir sayfa yenilendiğinde veya yüklendiğinde, yeni bir kimliğe sahip yeni bir html öğesi alır.

Yani, örneğin "bağlantı" metniyle bir bağlantıya tıklamak istediğinizi varsayalım:

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 Pythonic, yeniden kullanılabilir, genel yardım 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 her selenyum etkileşiminde kullanabilirsiniz:

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

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

Daha fazla bilgi blog yazısı bu konuda


10
2017-09-03 18:26



Çözümünüzü uygulayan java kodu için tekrar arama yapmadan önce web sayfanızı okudum. Şimdiye kadar hiçbir şey ... - andrew lorien


Belirli bir öğenin yüklenmesini beklemek isterseniz, isDisplayed() bir yöntem 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;
    }
}

(Şu adresten 5 Dakika Başlarken Kılavuzu)


9
2018-05-24 08:57



Bir yıl sonra (şu anki Selenium sürüm 2.23.1), yok RenderedWebElement API’da Ancak, isDisplayed() yöntem artık doğrudan kullanılabilir WebElement. - Petr Janeček
Kaçınılabilirken yoklama korkunç olur. - reinierpost