Selenium에서 페이지 로드 대기
Selenium 2.0이 페이지가 로드될 때까지 기다리도록 하려면 어떻게 해야 합니까?
다음 코드를 사용하여 페이지 로드를 확인할 수도 있습니다.
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"));
클래스 WebDriverWait 사용
이쪽도 참조해 주세요.
C#과 같은 요소를 보여줄 수 있습니다.
WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));
_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement")));
는, 「」를 합니다.findElement
WebDriver는 요소를 찾거나 타임아웃 값에 도달할 때까지 해당 요소를 폴링합니다.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
송신원: 암묵적 정의
일반적으로 Selenium 2.0에서는 웹 드라이버는 페이지가 로딩된 것을 확인한 후에만 콜 코드로 제어를 되돌립니다.않을 , 수 있습니다.waitforelemement
콜을 순환시킵니다.findelement
검색되거나 타임아웃될 때까지(타임아웃을 설정할 수 있습니다).
루비 구현:
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
@driver.execute_script("return document.readyState;") == "complete"
}
수 요.System.out
purposeline을 위해 됩니다. 이치노
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");
}
});
}
이러한 솔루션은 모두 특정 케이스에서는 문제가 없지만 적어도 몇 가지 문제 중 하나로 인해 문제가 발생합니다.
이것들은 충분히 범용적이지 않습니다.그것들은, 어느 특정의 조건이, 당신이 가는 페이지에 해당하는 것을 미리 알고 싶다고 생각하고 있습니다(예를 들면, 몇개의 요소가 표시됩니다).
새 페이지뿐만 아니라 이전 페이지에 실제로 있는 요소를 사용하는 레이스 조건에 대해 열려 있습니다.
다음은 이 문제를 회피하는 범용 솔루션(Python)에 대한 저의 시도입니다.
우선, 일반적인 「대기」기능(WebDriverWait를 사용하고 싶은 경우는, WebDriverWait 를 사용해 주세요)이 있습니다.
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__))
다음으로 이 모든 ( ID는 레벨이다.<html>
또는시 요소가 .페이지를 새로 고치거나 로드하면 새 ID를 가진 새 html 요소가 나타납니다.
예를 들어 다음과 같이 "내 링크"라는 텍스트가 있는 링크를 클릭한다고 가정합니다.
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)
더 많은 Phythonic, 재사용 가능한 범용 도우미를 위해 컨텍스트 관리자를 만들 수 있습니다.
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)
그리고 셀레늄 상호작용에 사용할 수 있습니다.
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
방탄인 것 같아!당신은 어떻게 생각하나요?
WebDriverWait wait = new WebDriverWait(myDriver, Duration.ofSeconds(15));
wait.until(webDriver -> "complete".equals(((JavascriptExecutor) webDriver)
.executeScript("return document.readyState")));
서 ★★★★★myDriver
는 입니다.WebDriver
참조object(오브젝트).
주의: 이 방법은 주의해 주십시오.document.readyState
는, DOM
다음 클래스를 사용하여 추가 액션을 수행하기 전에 요소가 웹 페이지에 표시될 때까지 명시적으로 기다릴 수도 있습니다.
.ExpectedConditions
: class: : 요소가를 확인합니다.
WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));
것은, 을 참조하십시오.ExpectedConditions class Javadoc
확인할 수 있는 모든 조건 목록을 표시합니다.
Imran의 답변은 Java 7용으로 재탕되었다.
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");
}
});
이것은 Web Driver의 심각한 제한인 것 같습니다.요소를 기다린다고 해서 페이지가 로드되는 것은 아닙니다.특히 DOM은 완전히 빌드(온레디 상태)할 수 있기 때문에 JS는 아직 실행 중이고 CSS와 이미지는 아직 로드 중입니다.
가장 간단한 해결책은 모든 것이 초기화된 후 온로드 이벤트에 JS 변수를 설정하고 Selenium에서 이 JS 변수를 확인하고 기다리는 것이라고 생각합니다.
" " 를 할 수 .isDisplayed()
의 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분 시작 가이드'의 예)
이 모든 답변들은 너무 많은 코드를 필요로 한다.이것은 매우 흔한 일이기 때문에 간단한 것입니다.
간단한 Javascript를 웹드라이버에 삽입하여 체크하는 것은 어떨까요?이것이 웹 스크레이퍼 클래스에서 사용하는 방법입니다.Javascript는 몰라도 기본입니다.
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
이 조건이 지정될 때까지 이 대기에서 명시적으로 대기하거나 조건부 대기하십시오.
WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));
모든 웹 요소가 60초 동안 대기합니다.
지정된 시간까지 페이지의 모든 요소를 암묵적으로 기다립니다.
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
모든 웹 요소가 60초 동안 대기합니다.
로드 대기 중인 페이지에서 다음에 어떤 요소와 대화할 것인지 일반적으로 알고 있기 때문에 술어가 첫 번째 선택이 아니었던 것이 놀랍습니다. 내는 입니다.waitForElementByID(String id)
★★★★★★★★★★★★★★★★★」waitForElemetVisibleByClass(String className)
페이지 로드나 페이지 콘텐츠 변경을 위해 필요한 장소에서 사용하고 재사용할 수 있습니다.
예를들면,
내 시험 수업에서:
driverWait.until(textIsPresent("expectedText");
테스트 클래스 부모:
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);
}
많은 것 같지만, 몇 번이고 체크할 수 있는 간격과 타임 아웃까지의 최종 대기 시간을 설정할 수 있습니다.또한 이러한 방법을 재사용할 수 있습니다.
예에서는 및 .WebDriver driver
및WebDriverWait driverWait
.
이게 도움이 됐으면 좋겠어요.
지정된 시간까지 페이지의 모든 요소를 암묵적으로 기다립니다.
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
30초 동안 페이지의 모든 요소를 기다립니다.
또 다른 대기는 명시적 대기 또는 이 대기 상태에서 지정된 조건이 될 때까지의 조건부 대기입니다.
WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
id에서는 페이지가 로드되는 즉시 페이지에 구분하여 표시되는 정적 요소 ID를 부여합니다.
WebDriver용 Java 바인딩을 사용할 때 페이지 로드를 기다리는 가장 좋은 방법은 PageFactory에서 Page Object 설계 패턴을 사용하는 것입니다. 하면, 「 」를 할 수 있습니다.AjaxElementLocatorFactory
즉, 고객의 모든 요소를 글로벌하게 기다리는 역할을 합니다.드롭박스나 복잡한 자바스크립트 전환 등의 요소에 제한이 있지만, 필요한 코드 양을 대폭 줄이고 테스트 시간을 단축할 수 있습니다.좋은 예는 이 블로그 포스트에서 찾을 수 있습니다.코어 Java에 대한 기본적인 이해가 전제되어 있습니다.
http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html
스크립트에서 아래 함수를 호출합니다.javascript를 사용하여 페이지가 로드되지 않을 때까지 기다립니다.
public static boolean isloadComplete(WebDriver driver)
{
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
|| ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
Node JS 솔루션:
Nodejs에서는 약속을 통해 얻을 수 있습니다.
이 코드를 쓰면 페이지가 완전히 로딩되어 있는 것을 확인할 수 있습니다.
driver.get('www.sidanmor.com').then(()=> {
// here the page is fully loaded!!!
// do your stuff...
}).catch(console.log.bind(console));
이 코드를 작성하면 네비게이트가 되고 셀레늄은 3초 동안...
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...
this.get( url ) → Thenable<undefined>
지정된 URL로 이동하는 명령을 스케줄링합니다.
문서 로드가 완료되면 해결될 약속을 반환합니다.
하여 을 할 수 .pageLoadTimeout
다음의 예에서는, 페이지가 로드되는 데 20초 이상 걸리는 경우는, 페이지 새로고침의 예외가 발생합니다.
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);
/**
* 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;
}
});
}
문서의 일부만 변경되는 경우 문서에서 요소로 변경할 수 있습니다.
이 기술은 그 이후부터의 답변에서 영감을 얻었다.
SeleniumWaiter:
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);
}
};
}
}
사용방법:
_waiter = new SeleniumWaiter(_driver);
try {
_waiter.waitForMe(By.xpath("//..."), 10);
}
catch (Exception e) {
// Error
}
간단한 방법:
long timeOut = 5000;
long end = System.currentTimeMillis() + timeOut;
while (System.currentTimeMillis() < end) {
if (String.valueOf(
((JavascriptExecutor) driver)
.executeScript("return document.readyState"))
.equals("complete")) {
break;
}
}
것 중 가장 은 '아예'를 하는 것입니다.stalenessOf
예상 조건: "예상 조건"
예:
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));
오래된 HTML 태그가 오래될 때까지 10초 정도 기다린 후 발생하지 않으면 예외를 발생시킵니다.
node + selenium-webdriver (현재 버전 3.5.0)를 사용하고 있습니다.제가 하는 일은:
var webdriver = require('selenium-webdriver'),
driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
return state === 'complete';
}))
기다리셔도 됩니다.셀레늄에는 기본적으로 두 가지 종류의 대기 시간이 있다.
- 암묵적 대기
- 명시적 대기
- 암묵적 대기
이것은 매우 간단합니다.아래 구문을 참조해 주세요.
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- 명시적 대기
지정된 조건이 발생할 때까지 이 대기에서 명시적으로 대기하거나 조건부 대기하십시오.
WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
에도 '먹다'는 '먹다'와 같은 할 수 있습니다.visblityOf()
,visblityOfElement()
셀레나이드를 사용하는 경우:
public static final Long SHORT_WAIT = 5000L; // 5 seconds
$("some_css_selector").waitUntil(Condition.appear, SHORT_WAIT);
자세한 내용은 http://selenide.org/javadoc/3.0/com/codeborne/selenide/Condition.html 를 참조해 주세요.
저의 경우, 다음과 같이 페이지 로드 상태를 파악했습니다.당사의 어플리케이션에는 gif 로딩이 존재하며, 스크립트 내에서 불필요한 대기시간을 없애기 위해 다음과 같이 듣습니다.
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")));
}
여기서 xpath는 HTML DOM에서 gif를 찾습니다.그 후 작업 방법을 구현할 수도 있습니다.클릭하세요.
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();
}
웹 페이지에 요소가 표시될 때까지 명시적으로 기다릴 수 있습니다(예:element.click()
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"));
}
}
);
이것은 비슷한 시나리오에서 사용한 것으로, 정상적으로 동작합니다.
Selenium이 클릭 후 페이지 로드를 대기하도록 하는 방법은 다음과 같습니다.
- 를 「」에 합니다.
WebElement
전전페페페페페페 - 링크를 클릭하세요.
- keepationsations keep の keep keep keep 。
WebElement
StaleElementReferenceException
집니니다
샘플 코드:
WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
try
{
link.isDisplayed();
return false;
}
catch (StaleElementReferenceException unused)
{
return true;
}
});
언급URL : https://stackoverflow.com/questions/5868439/wait-for-page-load-in-selenium
'it-source' 카테고리의 다른 글
Java에 Null Output Stream이 있습니까? (0) | 2022.11.01 |
---|---|
Python에서 목록의 중앙값을 찾는 중 (0) | 2022.11.01 |
Panda GroupBy 출력을 Series에서 DataFrame으로 변환 (0) | 2022.10.31 |
터미널에서 JavaScript 스크립트를 실행하려면 어떻게 해야 합니까? (0) | 2022.10.31 |
MySQL에서 STRAYT_JOIN을 사용하는 경우 (0) | 2022.10.31 |