[JAVA 6#] [Web Automation 6#] Controlling STEEMIT web pages with Selenium #4 WebDriverWait [KR]

in #kr6 years ago

redsjavahouse1591357_1280.jpg
image source: pixabay


오늘은 webdriver의 대기 시간에 대해 간단하게 알아본다. 웹페이지는 네트워크 혹은 다른 문제로 인해 태그가 늦게 노출될 수 있는데 당연하게도 노출되지도 않은 태그에 액션을 추가하면 Exception 이 발생한다. 해서 지난 몇번의 코드에는 강제로 sleep()을 주어 회피했어야 했다. 하지만 강제로 시간 대기하면 코드가 더러워지고, 전체적으로 실행 속도, 효율도 썩 좋좋은편이 아니다. 이런 이유에서일까, Selenium에서는 대기 방법을 제공하는데 이름하여 implicitly Wait, Explicitly Wait, Fluent Wait 세가지를 제공한다.

1. implicitly Wait

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

Webdriver의 전체 생명주기에 작용하는 기능이다. 단일 태그가 아닌 페이지의 모든 태그가 불러져 왔는지 체크한다. 세 방법중에서 가장 쉬운 방법이고 보통 코드 앞부분에 쓰여 대기시간을 초기화한다. sleep() 강제대기와 다른 부분은 태그를 빨리 찾으면 바로 다음으로 넘어가는 스마트한 면이 있다. manage()의 timeOuts() 내에 속해 있고, 인자는 대기시간과 시간 단위 단 두개다.
image.png

단점 - 전체 페이지가 불러져와야 pass 되므로 일부 상황에서는 도리여 비효율적인 부분도 있다. 예를 들면 일부 js가 로딩이 되지 않은 경우(브라우저 좌상단 로딩표시가 계속 표시되는 경우), 원하는 태그는 이미 발견되었음에도 pass되지 않고 기다린다.

2. Explicitly Wait

Wait<WebDriver> wait = new WebDriverWait(driver, 2);
wait.until(ExpectedConditions.presenceOfElementLocated(By.linkText("로그인dddd")));

WebDriverWait는 의도한 태그에 대기시간을 적용할 수 있다. 자유도가 높다는 뜻이다. 인자는 최소 두개이고 driver 객체와 대기시간을 초단위로 설정할 수 있다.
until()와 꼭 같이 사용해야 하는데 코드가 좀 길어지는 단점이 있다. until() 은 Selenium에서 제공하는 ExpectedConditions 클래스의 다양한 조건을 넣을 수 있다. ExpectedConditions 상세 페이지 가기

또한 WebDriverWait의 상위 클래스인 FluentWait 클래스의 메서드도 같이 사용할 수 있다. FluentWait는 자유도가 좀 더 높은데 아래와 같은 몇개의 메서드가 있다.
ignoring() - 특정 Exception을 무시한다.
withTimeout() - 타임아웃 시간을 설정한다.
pollingEvery() - 체크 간격을 설정한다.

(FluentWait는 인스턴스를 직접 생성해서 사용할 수도 있다. )


위에서 정리한 내용을 코드로 정리하면 아래와 같다.

package com.steem.webatuo;

import java.time.Duration;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

import io.github.bonigarcia.wdm.WebDriverManager;

public class Steemit {

    public static void main(String[] args) throws InterruptedException {
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver();
        driver.get("https://steemit.com/@june0620/feed");
        driver.manage().window().maximize();

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

        Wait<WebDriver> wait1 = new WebDriverWait(driver, 2);
        wait1.until(ExpectedConditions.presenceOfElementLocated(By.linkText("로그인dddd")));
        
        
        Wait<WebDriver> wait2 = new WebDriverWait(driver, 2).
                ignoring(NoSuchElementException.class).
                withMessage("에러 났드~~~~~~아!!!").
                pollingEvery(Duration.ofMillis(700));
        wait2.until(ExpectedConditions.presenceOfElementLocated(By.linkText("로그인dddd")));
        

        Wait<WebDriver> wait3 = new FluentWait<WebDriver>(driver).
                ignoring(NoSuchElementException.class).
                withTimeout(Duration.ofSeconds(20)).
                withMessage("에러 났드~~~~~~아!!!").
                pollingEvery(Duration.ofMillis(700));
        wait3.until(ExpectedConditions.presenceOfElementLocated(By.linkText("로그인dddd")));

}

.
.
.
.
[Cookie 😅]
Seleniun java lib version: 3.141.59

Sort:  

@tipu curate
我来了帅锅好🌹🌹🌹

Posted using Partiko Android

你来了? 👍😀🤩
多谢tipu,最近多加小心身体啊 非常时期😄

我守着你😅 还是被错过你两次中午我很少看到你🤭

你也知道了啊 你们那边没事吧 你也要和家人保重身体哈

Posted using Partiko Android

这里也有很多人都戴口罩😷 哈哈

帅哥/美女!还在发愁自己的好文没人发现,收益惨淡吗?记得加上cn-curation标签,让飞鸽传书 帮你走出困境吧!假如我的留言打扰到你,请回复“取消”。

Coin Marketplace

STEEM 0.12
TRX 0.34
JST 0.032
BTC 109657.83
ETH 4023.33
USDT 1.00
SBD 0.75