๐ŸŒฟ Spring

์ž๋ฐ”, Spring Boot๋กœ ํฌ๋กค๋งํ•˜๊ธฐ - Selenium ์ด์šฉ (๋™์ ํŽ˜์ด์ง€), ์†๋„ ๊ฐœ์„  ๋ฐฉ๋ฒ•

์—ฐ_์šฐ๋ฆฌ 2022. 3. 8. 00:23
๋ฐ˜์‘ํ˜•

๋ชฉ์ฐจ

     

     

    ์ด์ „๊ธ€

     

    ์ž๋ฐ”, Spring Boot๋กœ ํฌ๋กค๋งํ•˜๊ธฐ - Jsoup ์ด์šฉ (์ •์ ํŽ˜์ด์ง€)

    ๋ชฉ์ฐจ Jsoup์ด๋ž€? jsoup์€ Dom๋ฉ”์„œ๋“œ์™€ CSS Selector๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋Š” Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ํฌ๋กค๋งํ•ด๋ณด๊ธฐ ํฌ๋กค๋งํ•  URL ์ค€๋น„, Dom Selector ์ฐพ๊ธฐ ๋‚˜๋Š” ๋‹จ์–ด์žฅ ์•ฑ์„ ๋งŒ๋“ค๋ ค๊ณ ํ•œ๋‹ค. ๋‹จ

    lotuus.tistory.com

     

     

    Selenium์ด๋ž€?

    ์…€๋ ˆ๋‹ˆ์›€์€ ์‚ฌ์‹ค ์›น์‚ฌ์ดํŠธ ํ…Œ์ŠคํŠธ ๋„๊ตฌ์ด๋‹ค.

    ์‚ฌ๋žŒ์ด ์†์œผ๋กœ ์ผ์ผ์ด ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ผœ์„œ ์›น์‚ฌ์ดํŠธ๋ฅผ ํ™•์ธํ•˜๊ณ , ์ˆ˜์ •ํ•˜๊ณ , ํ…Œ์ŠคํŠธํ•˜๊ณ ... ํ•˜๋Š”๊ฒŒ ๋ฒˆ๊ฑฐ๋กœ์›Œ์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์›น๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋™์ž‘์‹œ์ผœ ํ…Œ์ŠคํŠธํ•˜์ž! ํ•˜๊ณ  ๋‚˜์˜จ ๊ธฐ์ˆ ์ธ๋ฐ, ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋™์ ์œผ๋กœ ๋ณ€ํ•˜๋Š” ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์…€๋ ˆ๋‹ˆ์›€์„ ํฌ๋กค๋ง์—์„œ ํ™œ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

     

     

     

    ํฌ๋กค๋ง ํ•ด๋ณด๊ธฐ

    SpringBoot build.gradle์— ์˜์กด์„ฑ ์ถ”๊ฐ€

    https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java ์ฐธ๊ณ 

    implementation 'org.seleniumhq.selenium:selenium-java:4.1.2'

     

     

    ์…€๋ ˆ๋‹ˆ์›€ ๋“œ๋ผ์ด๋ฒ„ ๋‹ค์šด๋กœ๋“œ

    ์ปดํ“จํ„ฐ์— ์„ค์น˜๋œ ํฌ๋กฌ์˜ ๋ฒ„์ „์„ ํ™•์ธํ•œ๋‹ค.

     

     

     

    https://chromedriver.chromium.org/downloads

    ์œ„ ๋งํฌ์—์„œ ํ•ด๋‹น๋˜๋Š” ๋ฒ„์ „์— ๋งž๊ฒŒ ๋‹ค์šด๋กœ๋“œํ•œ๋‹ค. (์œˆ๋„์šฐ 64๋น„ํŠธ๋„ 32๋น„ํŠธ๋กœ ๋‹ค์šด๋ฐ›๋Š”๋‹ค)

     

     

     

     

    ํฌ๋กค๋ง ์ฝ”๋“œ

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.springframework.stereotype.Component;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    @Component
    public class CrawlingExample {
        private WebDriver driver;
    
        private static final String url = "https://yourei.jp/่…•ใ‚’็ฃจใ";
        public void process() {
            System.setProperty("webdriver.chrome.driver", "C:\\Users\\Desktop\\chromedriver.exe");
            //ํฌ๋กฌ ๋“œ๋ผ์ด๋ฒ„ ์…‹ํŒ… (๋“œ๋ผ์ด๋ฒ„ ์„ค์น˜ํ•œ ๊ฒฝ๋กœ ์ž…๋ ฅ)
    
            driver = new ChromeDriver();
            //๋ธŒ๋ผ์šฐ์ € ์„ ํƒ
    
            try {
                getDataList();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            driver.close();	//ํƒญ ๋‹ซ๊ธฐ
            driver.quit();	//๋ธŒ๋ผ์šฐ์ € ๋‹ซ๊ธฐ
        }
    
    
        /**
         * data๊ฐ€์ ธ์˜ค๊ธฐ
         */
        private List<String> getDataList() throws InterruptedException {
            List<String> list = new ArrayList<>();
    
            driver.get(url);    //๋ธŒ๋ผ์šฐ์ €์—์„œ url๋กœ ์ด๋™ํ•œ๋‹ค.
            Thread.sleep(1000); //๋ธŒ๋ผ์šฐ์ € ๋กœ๋”ฉ๋ ๋•Œ๊นŒ์ง€ ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
    
            //WebElement sentence = driver.findElement(By.cssSelector("#sentence-example-list .sentence-list li"));
            //System.out.println(sentence.getText());
            //ใ“ใฎๅ…ˆ่…•ใ‚’็ฃจใ„ใฆใ„ใ‘ใฐใ€ใ„ใคใ‹ใฏใ“ใฎ็”ทใซๅ‹ใฆใ‚‹ๆ—ฅใŒใใ‚‹ใฎใ ใ‚ใ†ใ‹ใ€‚ ...
            //ใƒ™ใƒ‹ใƒผๆพๅฑฑใ€Ž้ขจใ‚ˆใ€‚้พใซๅฑŠใ„ใฆใ„ใ‚‹ใ‹(ไธ‹)ใ€
            // findElement (๋์— s์—†์Œ) ๋Š” ํ•ด๋‹น๋˜๋Š” ์„ ํƒ์ž์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค
    
            List<WebElement> elements = driver.findElements(By.cssSelector("#sentence-example-list .sentence-list li"));
            for (WebElement element : elements) {
                System.out.println("----------------------------");
                System.out.println(element);	//โญ
            }
            
            return list;
        }
    
    }

    ๋ฉ”์„œ๋“œ ์ฐธ๊ณ 

    https://www.selenium.dev/documentation/webdriver/elements/finders/#find-elements-from-element

     

    findElement, findElements ์•ˆ์— By.id, By.class, By.tagName, By.cssSelector... ์„ ์ž‘์„ฑํ•˜์—ฌ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

     

     

     

     

     

    โญ๋ถ€๋ถ„์„ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๋œ๋‹ค

    ----------------------------
    ใ“ใฎๅ…ˆ่…•ใ‚’็ฃจใ„ใฆใ„ใ‘ใฐใ€ใ„ใคใ‹ใฏใ“ใฎ็”ทใซๅ‹ใฆใ‚‹ๆ—ฅใŒใใ‚‹ใฎใ ใ‚ใ†ใ‹ใ€‚ ...
    ใƒ™ใƒ‹ใƒผๆพๅฑฑใ€Ž้ขจใ‚ˆใ€‚้พใซๅฑŠใ„ใฆใ„ใ‚‹ใ‹(ไธ‹)ใ€
    ----------------------------
    ๆœ€้ซ˜ใฎๆญฆ่Šธ่€…ใŸใ‚‹ในใใ“ใจใ‚’็›ฎๆจ™ใจใ—ใ€ๅทฑใฎ่…•ใ‚’็ฃจใ็ถšใ‘ใ‚‹ใ“ใจใงใ‚ใ‚‹ใ€‚ ...
    ไผ่ฆ‹ๅฅไบŒใ€Žใ‚ตใ‚คใƒฌใƒณใฎๅ“€ๆญŒใŒ่žใ“ใˆใ‚‹ใ€
    ----------------------------
    
    ....
    
    ----------------------------
    ใ„ใใ‚‰ๆˆฆใ„ใฎ่…•
    ใ†ใง
    ใ‚’็ฃจ
    ใฟใŒ
    ใ„ใŸใฃใฆใ€ใใ‚Œใ ใ‘ใ˜ใ‚ƒ่‹ฑ้›„ใซใชใ‚Œใญใˆใ€‚ ...
    ๅฑฑๆœฌๅผ˜ใ€Žใ‚ตใƒผใƒฉใฎๅ†’้™บ 5 ๅนธใ›ใ‚’ใคใ‹ใฟใŸใ„ !ใ€
    ----------------------------

     

    ๋งจ ๋งˆ์ง€๋ง‰์— ํ•ด๋‹น๋˜๋Š” ๋ถ€๋ถ„์„ ํ™•์ธํ•ด๋ณด๋ฉด ์œ„์˜ ํ›ˆ๋…๋„ ๊ฐ™์ด ์ถœ๋ ฅ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

     

     

     

     

     

    ํ›ˆ๋…์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด๋ณด๊ฒ ๋‹ค.

    /**
         * data๊ฐ€์ ธ์˜ค๊ธฐ
         */
        private List<String> getDataList() throws InterruptedException {
            List<String> list = new ArrayList<>();
    
            driver.get(url);    //๋ธŒ๋ผ์šฐ์ €์—์„œ url๋กœ ์ด๋™ํ•œ๋‹ค.
            Thread.sleep(1000); //๋ธŒ๋ผ์šฐ์ € ๋กœ๋”ฉ๋ ๋•Œ๊นŒ์ง€ ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
    
            List<WebElement> elements = driver.findElements(By.cssSelector("#sentence-example-list .sentence-list li"));
            for (WebElement element : elements) {
                System.out.println("----------------------------");
                System.out.println(element.getText());
    
                List<WebElement> rubys = element.findElements(By.tagName("ruby"));
                for (WebElement ruby : rubys) {
                    System.out.println("ruby : " + ruby.getText());
    
                    List<WebElement> rts = ruby.findElements(By.tagName("rt"));
                    for (WebElement rt : rts) {
                        System.out.println("rt : " + rt.getText());
                    }
                }
    
            }
    
            return list;
        }
    ----------------------------
    ใ„ใใ‚‰ๆˆฆใ„ใฎ่…•
    ใ†ใง
    ใ‚’็ฃจ
    ใฟใŒ
    ใ„ใŸใฃใฆใ€ใใ‚Œใ ใ‘ใ˜ใ‚ƒ่‹ฑ้›„ใซใชใ‚Œใญใˆใ€‚ ...
    ๅฑฑๆœฌๅผ˜ใ€Žใ‚ตใƒผใƒฉใฎๅ†’้™บ 5 ๅนธใ›ใ‚’ใคใ‹ใฟใŸใ„ !ใ€
    ruby : ่…•
    ใ†ใง
    rt : ใ†ใง
    ruby : ็ฃจ
    ใฟใŒ
    rt : ใฟใŒ
    ----------------------------

    ์ด๋ ‡๊ฒŒ element์•ˆ์—์„œ๋„ findElements๋ฅผ ํ†ตํ•ด ๋” ์ž์„ธํ•˜๊ฒŒ ์š”์†Œ๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

     

     

     

     

    Selenium ์‹คํ–‰์‹œ๊ฐ„๊ณผ ์†๋„

    ํ˜„์žฌ ์ „์ฒด li (18๊ฐœ)๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„์€ ๋นจ๋ผ์•ผ 8์ดˆ์ด๋‹ค. ๋Š๋ฆด๋• 20์ดˆ๋Œ€๊ฐ€ ๋‚˜์˜จ๋‹ค..

    ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด 2๊ฐ€์ง€๋ฅผ ์„ค์ •ํ•ด๋ณด์ž

     

     

    ๋“œ๋ผ์ด๋ฒ„ ์˜ต์…˜

    ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ด๋ณด๋ฉด ์•„๋ž˜ ๋ฌธ๊ตฌ๊ฐ€ ํ‘œ์‹œ๋œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰๋˜์—ˆ๋‹ค๊ฐ€ ์ข…๋ฃŒ๋˜๋Š”๋ฐ,

    ์‚ฌ๋žŒ์ด ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‹คํ–‰ํ•˜๊ณ , url์„ ์ด๋™ํ•˜๊ณ , ์ด๋ฏธ์ง€๋„ ๋กœ๋”ฉํ•˜๊ณ ... ํ•ด์•ผํ•˜๋‹ˆ ๋‹น์—ฐํžˆ ๋Š๋ฆด ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

     

     

     

    ํฌ๋กค๋งํ• ๋•Œ ๊ตณ์ด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ผœ์ ธ์•ผํ•  ์ด์œ ๊ฐ€ ์—†๋‹ค.

    ๋˜ํ•œ ๊ด‘๊ณ ๋กœ ๋œจ๋Š” ์ด๋ฏธ์ง€๋“ค๋„ ๋‹ค์šด๋ฐ›์„ ์ด์œ  ์—†๋‹ค.

    public void process() {
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\Desktop\\chromedriver.exe");
        //ํฌ๋กฌ ๋“œ๋ผ์ด๋ฒ„ ์…‹ํŒ…
    
        //driver = new ChromeDriver();
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--disable-popup-blocking");       //ํŒ์—…์•ˆ๋„์›€
        options.addArguments("headless");                       //๋ธŒ๋ผ์šฐ์ € ์•ˆ๋„์›€
        options.addArguments("--disable-gpu");			//gpu ๋น„ํ™œ์„ฑํ™”
        options.addArguments("--blink-settings=imagesEnabled=false"); //์ด๋ฏธ์ง€ ๋‹ค์šด ์•ˆ๋ฐ›์Œ
        driver = new ChromeDriver(options);
    
        try {
            getDataList();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        driver.close();
        driver.quit();
    }

    8์ดˆ -> 7์ดˆ๋กœ 1์ดˆ ๊ฐ์†Œํ–ˆ๋‹ค.

    ๋˜ํ•œ ์ตœ์†Œ 8์ดˆ ~ ์ตœ๋Œ€20์ดˆ์˜ ๊ฐ„๊ฒฉ์ด ๋งŽ์ด ์ขํ˜€์กŒ๋‹ค.

     

     

     

     

    ํŽ˜์ด์ง€ ๋กœ๋”ฉ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐฉ๋ฒ•

    ์…€๋ ˆ๋‹ˆ์›€์€ ๋™์  ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋งŒํผ, ํŽ˜์ด์ง€๊ฐ€ ๋ชจ๋‘ ๋กœ๋”ฉ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํŒŒ์‹ฑ ๊ฒฐ๊ณผ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

    ํŽ˜์ด์ง€ ๋กœ๋”ฉ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š”๋ฐ์—๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

     

     

    1. Thread.sleep(10000) : ๋ฌด์กฐ๊ฑด 10์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

    Thread.sleep(10000);
    ์žฅ์  ๊ฐ€์žฅ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๋‹จ์  ํŽ˜์ด์ง€๊ฐ€ 3์ดˆ ์ด๋‚ด์— ๋กœ๋”ฉ์™„๋ฃŒ๋˜๋ฉด ๋ถˆํ•„์š”ํ•œ 2์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผํ•˜๋ฉฐ,
    ํŽ˜์ด์ง€๊ฐ€ 3์ดˆ ์ดํ›„์— ๋กœ๋”ฉ์™„๋ฃŒ๋˜๋ฉด ์ดํ›„ InterruptedException์ด ๋ฐœ์ƒํ•˜๊ฒŒ๋œ๋‹ค.
    ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋กœ๋”ฉ์‹œ๊ฐ„์„ ์ž„์˜๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์€ ์•ˆ์ข‹์€ ์„ ํƒ์ด๋‹ค.

     

     

    2. Implicitly wait : ์›นํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ๋กœ๋”ฉ๋ ๋•Œ๊นŒ์ง€ ์ตœ๋Œ€ N์ดˆ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

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

    driver.get()ํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์ตœ๋Œ€ 10์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

    10์ดˆ ์ด์ „์— ์›นํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ๋œ๋‹ค.

    10์ดˆ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ๋œ๋‹ค. ์ด๋•Œ ์›นํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด 10์ดˆ๊ฐ€ ์ง€๋‚ฌ๋Š”๋ฐ๋„ ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

    ์žฅ์  ์›นํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด์„œ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๋‹จ์  10์ดˆ ์ด์ „์— ์›นํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜์—ˆ์ง€๋งŒ ๋™์ ์ž‘์—…(์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ)์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด
    ์ •ํ™•ํ•˜์ง€ ์•Š์€ ํŒŒ์‹ฑ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ฒŒ๋œ๋‹ค. (ex. ๋ธ”๋กœ๊ทธ ๋ฐฉ๋ฌธ ์‹œ ๋ธ”๋กœ๊ทธ ๋‚ด์šฉ์ด ๋จผ์ € ๋ณด์ด๊ณ  ๋ช‡์ดˆ ํ›„์— ๊ด‘๊ณ ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ)

     

     

    3. Explicitly wait : ์›นํŽ˜์ด์ง€ ์ผ๋ถ€๋ถ„์ด ๋‚˜ํƒ€๋‚ ๋•Œ๊นŒ์ง€ ์ตœ๋Œ€ N์ดˆ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

    private List<String> getDataList() throws InterruptedException {
        List<String> list = new ArrayList<>();
    
        WebDriverWait webDriverWait = new WebDriverWait(driver, 10);	//โญโญโญ
        //๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์‹คํ–‰๋œ ๋’ค ์ตœ๋Œ€ 10์ดˆ ๊ธฐ๋‹ค๋ฆฌ๊ฒ ๋‹ค.
    
        driver.get(url);    //๋ธŒ๋ผ์šฐ์ €์—์„œ url๋กœ ์ด๋™ํ•œ๋‹ค.
        //Thread.sleep(1000); //๋ธŒ๋ผ์šฐ์ € ๋กœ๋”ฉ๋ ๋•Œ๊นŒ์ง€ ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.	
    
        webDriverWait.until(	
                ExpectedConditions.presenceOfElementLocated(By.cssSelector("#sentence-example-list .sentence-list li"))
                //cssSelector๋กœ ์„ ํƒํ•œ ๋ถ€๋ถ„์ด ์กด์žฌํ• ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค๋ผ
        );	//โญโญโญ
    
        List<WebElement> elements = driver.findElements(By.cssSelector("#sentence-example-list .sentence-list li"));
        for (WebElement element : elements) {
            System.out.println("----------------------------");
            System.out.println(element.getText());
            
            ......
        }
        return list;
    }

    driver.get()ํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์ตœ๋Œ€ 10์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

    10์ดˆ ์ด์ „์— ๋‚ด๊ฐ€ ์ง€์ •ํ•œ ๋ถ€๋ถ„์˜ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ๋œ๋‹ค.

    10์ดˆ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ๋œ๋‹ค. ์ด๋•Œ ์›นํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด 10์ดˆ๊ฐ€ ์ง€๋‚ฌ๋Š”๋ฐ๋„ ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (implicitly์™€ ๋™์ผ)

    ์žฅ์  ์ผ๋ถ€๋ถ„์— ๋Œ€ํ•œ ExpectedConditions์˜ ๋กœ๋”ฉ ์กฐ๊ฑด์ด true๊ฐ€ ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€
    ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด์„œ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์ •ํ™•ํ•˜์ง€ ์•Š์€ ํŒŒ์‹ฑ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ์•„์ง„๋‹ค.

     

     

    ExpectedConditions

    (By locator๋Š” id, class, css ๋“ฑ๋“ฑ์˜ dom์š”์†Œ๋ฅผ ์„ ํƒํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.)

    visibilityOf(WebElement element) WebElement๊ฐ€ ํ™”๋ฉด์— ์ถœ๋ ฅ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
    visibilityOfElementLocated(By locator) locator๊ฐ€ ํ™”๋ฉด์— ์ถœ๋ ฅ๋ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
    presenseOfElementLocated(By locator) locator๊ฐ€ ์กด์žฌํ• ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
    (ํ™”๋ฉด์— ์ถœ๋ ฅ๋˜๋Š”์ง€๋Š” ์ฒดํฌํ•˜์ง€ ์•Š๋Š”๋‹ค.)

    ์ด์™ธ ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜ ๋ฌธ์„œ ์ฐธ๊ณ 

    https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html

     

     

    ํ”„๋กœ์ ํŠธ์— Explicitly wait - ExpectedConditions.presenseOfElementLocated๋ฅผ ์ ์šฉํ•˜์˜€๋‹ค.

    7์ดˆ -> 6์ดˆ๋กœ 1์ดˆ ๊ฐ์†Œํ–ˆ๋‹ค.

     

     

     

     

     

    ๊ฒฐ๋ก 

    ์…€๋ ˆ๋‹ˆ์›€์€ findElements๋กœ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ 

    ์š”์†Œ.click(), ์š”์†Œ.send_keys(~), ํŒ์—…์ฐฝ ์ด๋™, ์Šคํฌ๋กค ๋‚ด๋ฆฌ๊ธฐ... ๋“ฑ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    ๋‹ค์–‘ํ•œ ์ž‘์—…์€ https://gorokke.tistory.com/8โ€‹ ๋ฅผ ์ฐธ๊ณ ํ•˜์ž (์ •๋ฆฌ ์ž˜๋˜์–ด์žˆ๋‹ค)

     

    ์…€๋ ˆ๋‹ˆ์›€ ์‚ฌ์šฉ์‹œ ๋“œ๋ผ์ด๋ฒ„ ์˜ต์…˜๊ณผ Explicitly wait์€ ํ•„์ˆ˜๋กœ ์‚ฌ์šฉํ•ด์ฃผ์ž!!!!

    ๋ฐ˜์‘ํ˜•
    • ๋„ค์ด๋ฒ„ ๋ธ”๋Ÿฌ๊ทธ ๊ณต์œ ํ•˜๊ธฐ
    • ํŽ˜์ด์Šค๋ถ ๊ณต์œ ํ•˜๊ธฐ
    • ํŠธ์œ„ํ„ฐ ๊ณต์œ ํ•˜๊ธฐ
    • ๊ตฌ๊ธ€ ํ”Œ๋Ÿฌ์Šค ๊ณต์œ ํ•˜๊ธฐ
    • ์นด์นด์˜คํ†ก ๊ณต์œ ํ•˜๊ธฐ