자바 / 셀레니움(selenium)으로 크롤링하기 (4)

Joy·2022년 2월 26일
0

JAVA

목록 보기
21/22

무한스크롤까지 코드입력을 했다면, 하나의 요소뿐만 아니라, 로케이터와 일치하는 모든 요소에 대한 참조를 가져오기 위해 List를 사용한다.
List로 가져온 item 요소들은 객체이기 때문에 for문을 사용해서 조회해야 한다.
https://www.selenium.dev/documentation/webdriver/elements/finders/

각 콘텐츠의 상세페이지로 들어가 이미지, 제목 등을 크롤링할 예정이기 때문에 우선 상세페이지로 들어갈 url을 잡아준다.a태그 안에 있는 href가 상세페이지 주소이기 때문에 로케이터는 tagName이 된다.
String url = element.findElement(By.tagName("a")).getAttribute("href");

상세페이지 url로 이동을 해줬다면 스레드로 시간차를 설정해주고, 이후 조회를 해서 println으로 조회가 잘 되는지 확인을 해주면 된다.

나의 경우 img 태그 안에 이미지와 제목이 둘 다 있어서 img 태그를 활용해서 데이터를 가져왔다.ex) 제목 가져오기:
System.out.println("title = " + element.findElement(By.tagName("img")).getAttribute("alt"));

ex) 콘텐츠 소개 가져오기:
상세페이지에서 페이지 소스 보기를 누르고,
중간에 보이는 줄거리를 제목과 똑같은 방법으로 가져와주면 된다.(다만 ott별로 페이지 소스가 다르기 때문에 해당 콘텐츠 줄거리가 없을 수도 있다ㅠ)

ex) 태그 가져오기:
cssSelector를 활용하였는데, 여러 태그들이 tag_wrap의 하위요소들로 있으니, 지정을 해준다.
By.cssSelector("div.tag_wrap > div")

package com.example.jsouptest;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@SpringBootApplication
public class JsoupTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(JsoupTestApplication.class, args).getBean(JsoupTestApplication.class).test();
    }

    public void test(){

        ChromeOptions options = new ChromeOptions();
        options.setPageLoadStrategy(PageLoadStrategy.NORMAL);

        WebDriver driver = new ChromeDriver(options);
        WebDriver driver1 = new ChromeDriver(options);

        try {
            driver.get("https://user.tving.com/pc/user/otherLogin.tving?loginType=20&from=pc&rtUrl=https://www.tving.com&csite=&isAuto=false");
            driver.findElement(By.xpath("//*[@id=\"a\"]")).sendKeys("ott가입아이디입력");
            driver.findElement(By.xpath("//*[@id=\"b\"]")).sendKeys("ott가입비밀번호입력");
            driver.findElement(By.xpath("//*[@id=\"doLoginBtn\"]")).click();
            System.out.println("로그인 성공 = " + driver.getCurrentUrl());


            driver1.get("https://user.tving.com/pc/user/otherLogin.tving?loginType=20&from=pc&rtUrl=https://www.tving.com&csite=&isAuto=false");
            driver1.findElement(By.xpath("//*[@id=\"a\"]")).sendKeys("ott가입아이디입력");
            driver1.findElement(By.xpath("//*[@id=\"b\"]")).sendKeys("ott가입비밀번호입력");
            driver1.findElement(By.xpath("//*[@id=\"doLoginBtn\"]")).click();
            System.out.println("로그인 성공1 = " + driver1.getCurrentUrl());


            driver.navigate().to("https://www.tving.com"); 
            System.out.println("홈페이지 = " + driver.getCurrentUrl());

            driver.navigate().to("https://www.tving.com/tv"); 
            System.out.println("tv프로그램 = " + driver.getCurrentUrl());

            driver.navigate().to("https://www.tving.com/list/program?genre=PCA"); 
            System.out.println("tv프로그램>드라마 = " + driver.getCurrentUrl());

            WebElement item = driver.findElement(By.className("item"));

            var stTime = new Date().getTime(); 
            while (new Date().getTime() < stTime + 30000) { 
                Thread.sleep(500); 
                ((JavascriptExecutor)driver).executeScript("window.scrollTo(0, document.body.scrollHeight)", item);
            }

            //item에 대한 리스트 가져오기
            List<WebElement> elements = driver.findElements(By.className("item"));

            //item 요소 조회, item은 객체이기 때문에 for문을 사용해서 조회하기
            for (WebElement element : elements) {
                driver.manage().timeouts().implicitlyWait(100000, TimeUnit.MILLISECONDS);
                driver1.manage().timeouts().implicitlyWait(100000, TimeUnit.MILLISECONDS);

                String url = element.findElement(By.tagName("a")).getAttribute("href");
                driver1.navigate().to(url); //url로 이동
                Thread.sleep(500);

                //content 조회
                System.out.println("content = " + driver1.findElement(By.name("description")).getAttribute("content"));

                //title 조회
                System.out.println("title = " + element.findElement(By.tagName("img")).getAttribute("alt"));
                //title className으로 조회했을 때
                //System.out.println("title = " + element.findElement(By.className("item__title")).getText());

                //img 조회
                System.out.println("image = " + element.findElement(By.tagName("img")).getAttribute("src"));
                //img className으로 조회했을 때
                //System.out.println("image = " + element.findElement(By.cssSelector("img.loaded")).getAttribute("src"));

                //tag 조회, 하위요소
                List<WebElement> tags = driver1.findElements(By.cssSelector("div.tag_wrap > div"));

                for (WebElement webElement : tags) {
                    System.out.print("tag = " + webElement.getText() + " / ");
                }
            }
        } catch (InterruptedException e) { //sleep 잡아주기
            e.printStackTrace();
        } finally {
            driver.quit();
            driver1.quit();
        }
    }
}


profile
👻

0개의 댓글