반응형
Recent Posts
Recent Comments
관리 메뉴

개발잡부

[selenium] 동적생성 웹페이지 크롤링 본문

JAVA/java

[selenium] 동적생성 웹페이지 크롤링

닉의네임 2022. 1. 7. 14:21
반응형

https://ldh-6019.tistory.com/147

 

[selenium] Selenium 설치

동적으로 생성되는 웹페이지 (mathpix 사이트) 크롤링을 해야 하는 이슈가 있어서 selenium 으로 크롤링 크롬 드라이버 설치 크롬 버전확인 http://chromedriver.chromium.org/downloads 버전에 맞는 드라이버를..

ldh-6019.tistory.com

 

설치했으면 긁어보자

 

사이트 접속 -> 로그인 -> 리스트페이지 이동 -> 크롤링

package com.etoos.imagesearch.service;


import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.stereotype.Service;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Service
public class CrawlerService {

    private static WebElement element;

    public void getData() {

        System.setProperty("webdriver.chrome.driver", "/Users/doo/bin/chromedriver");
        
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");            // 전체화면으로 실행
//        options.addArguments("--window-size= 200, 200"); //실행되는 브라우저 크기를 지정할 수 있습니다. - 이것도 안먹히는데
//        options.addArguments("--start-fullscreen");            // 브라우저가 풀스크린 모드(F11)로 실행됩니다.
        options.addArguments("--disable-popup-blocking");    // 팝업 무시
        options.addArguments("--disable-default-apps");     // 기본앱 사용안함
        options.addArguments("user-agent=" + userAgent);
        options.addArguments("--blink-settings=imagesEnabled=false");            // 브라우저에서 이미지 로딩을 하지 않습니다.
        options.addArguments("--mute-audio");            // 브라우저에 음소거 옵션을 적용합니다.
        options.addArguments("incognito");            // 시크릿 모드의 브라우저가 실행됩니다.    

        
        ChromeDriver driver = new ChromeDriver(options);


        driver.executeScript("window.open('about:blank','_blank');");
        List<String> tabs = new ArrayList<String>(driver.getWindowHandles());


        driver.switchTo().window(tabs.get(0));

        driver.get("https://accounts.mathpix.com/ocr-api/2176285a-b09c-42c3-a6d0-ff4daa61e9a2/results");

        try {
            element = driver.findElement(By.name("email"));

            Thread.sleep(500);

            element.sendKeys("bbongdoo@아이디");
            element = driver.findElement(By.name("password"));
            element.sendKeys("패스워드");

            //전송
            element = driver.findElement(By.className("login"));
            element.submit();

            Thread.sleep(1000);

        } catch (InterruptedException e) {
            e.getStackTrace();
        }

        // 웹페이지 요청
        driver.get("https://accounts.mathpix.com/ocr-api/2176285a-b09c-42c3-a6d0-ff4daa61e9a2/results");

        try {

            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

        List<WebElement> muchoCheese = driver.findElements(By.cssSelector("table.user-data>tbody>tr"));

        muchoCheese.stream().forEach(e -> {
            String imageUrl = e.findElement(By.cssSelector("td.image-col>img")).getAttribute("src");
            Double confidence = Double.valueOf(e.findElement(By.cssSelector("td:nth-child(4)")).getText());
            String result = e.findElement(By.cssSelector("td:nth-child(5)")).getText();
            String registeredDate = e.findElement(By.cssSelector("td:nth-child(7)")).getText();
        });
    }
}

기본 세팅

 web driver 초기화 

WebDriver driver = new ChromeDriver();

web site로 이동 

driver.get("https://ldh-6019.tistory.com");

WebElement 혹은 List<WebElement>찾기 

  a. attribute 값으로 찾기 

    a-1. id : (id="email" 인 경우)

WebElement loginID = driver.findElement(By.id("email"));

    a-2. class : (class="userContent" 인 경우)

List<WebElement> posts  = driver.findElements(By.className("userContent"));

  b. linked text로 찾기 (link가 걸려있는 text가 "더 보기" 인 경우)

WebElement open = driver.findElement(By.linkText("더 보기"));

  c. xpath로 찾기 

    c-1. 절대경로 : 

WebElement div = driver.findElement(By.xpath("/html/body/div"));

    c-2. 상대경로(c-1 이용) : (현재위치 아래 "span" tagName이고 클래스는 "fbw" 인 아래에 p 태그들 찾기)

List<WebElement> posts = div.findElements(By.xpath(".//span[@class='fbw']/p"));

      c-2-1. xpath로 parent 지정 : (주의 : List가 아닌 단수의 WebElement만 가능)

  WebElement body = div.findElement(By.xpath(".."));

      c-2-2. xpath로 grand parent 지정 : 

  WebElement html = div.findElement(By.xpath("..//.."));

 

WebElement에서 attribute 값 추출하기 

WebElement 객체에 .getAttribute(key) 하면 value를 return한다

  element.getAttribute("data-ft");

 

login 하기 (form처리하기)  WebElement 객체에 .submit() 을 하면 form을 알아서 찾은 뒤 submit한다

  WebElement loginID = driver.findElement(By.id("id"));

  loginID.sendKeys(userId);

  WebElement loginPassword = driver.findElement(By.id("pass"));

  loginPassword.sendKeys(userPw);

  loginPassword.submit();

 

ajax wating 처리 

  클릭할 수 있을 때까지 기다리거나, 보일 때까지 기다리거나, 보이는지 여부를 bool 값으로 나타낼 수 있다

  (new WebDriverWait(driver,30)).until(ExpectedConditions.elementToBeClickable(element));



WebElement 찾기 연쇄적용 팁 : By는 메서드체인 방식으로 사용할 수 없다. 하지만 WebElement 객체를 단계로 밟아가면 연쇄적용이 가능하다

  WebElement authorWrap = driver.findElement(By.className("fwb"));

  WebElement author = authorWrap.findElement(By.xpath(".//a"));

  authorName = author.getText();

 

click 하기 : WebElement 객체에 .click() 한다. 

  element.click();

 

key 누르기 : Keys 객체를 이용한 뒤 WebElement 객체에 .sendKeys(keys) 한다

  String selectAll = Keys.chord(Keys.CONTROL, "a");

  element.sendKeys(selectAll);

 

iframe 지정 : "body"라는 이름의 frame을 바라보도록 지정한다. 0부터 시작하는 index 숫자로도 지정이 가능하다

  driver.switchTo().iframe("body");

 

반응형

'JAVA > java' 카테고리의 다른 글

[java] HttpUtils  (0) 2022.01.18
Json 파일 읽기 - json.simple  (0) 2022.01.11
[selenium] Selenium 설치  (0) 2022.01.07
AWS S3 파일업로드 테스트  (0) 2021.10.21
String to JsonObject  (0) 2021.10.07
Comments