[Java] Selenium을 사용하는 방법


Development note/Java  2020. 6. 4. 17:40

안녕하세요. 명월입니다.


이 글은 Java에서 Selenium을 사용하는 방법에 대한 글입니다.


Selenium에 대해서 Python이나 C#으로 소개를 한 적이 있습니다.

Selenium은 브라우져의 API를 이용하여 웹 화면 테스팅을 하기 위한 모듈입니다. Selenium은 무료 오픈 소스입니다.

Selenium으로 제어할 수 있는 브라우져는 firefox, Chrome, safari, IE등의 거의 메인 브라우저는 모두 접근이 가능합니다. 참고로 Selenium은 브라우저를 원격 제어하는 함으로 웹 서비스의 브라우저의 호환 테스팅, 자동화 테스팅에 적합한 모듈입니다. 웹 크롤링으로 사용하기에는 성능 및 환경의 제약으로 적합하지 않습니다.


여기서는 ChomeDriver를 이용해서 Selenium를 사용하겠습니다.

저 이미 설치되어 있는 Chrome의 버전을 확인해야 합니다.

크롬 브라우저의 오른쪽 상단의 메뉴를 클릭하고 Help -> About Google Chrome을 누릅니다.

그럼 위 이미지처럼 현재 버전이 나옵니다.


아래의 링크를 타고가서 앞자리가 같은 버젼을 선택합니다.

링크 - https://sites.google.com/a/chromium.org/chromedriver/downloads

저의 경우는 79.xxx버전이었기 때문에 79.xxx를 다운 받았습니다. 그리고 윈도우에서 사용할 것이기 때문에 윈도우 버전을 다운 받았습니다.

압축 파일 안에는 chromedriver.exe 파일이 있는데 적당한 폴더에 드라이버를 복사해 넣습니다. 저는 D드라이브의 work 폴더에 넣었습니다.

이제 Java 프로젝트를 열고 pom을 이용해서 라이브러리를 업데이트합니다.

레포지토리 - https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java/3.141.59

<dependency>
  <groupId>org.seleniumhq.selenium</groupId>
  <artifactId>selenium-server</artifactId>
  <version>2.53.0</version>
</dependency>

이제 Java 소스를 작성하겠습니다.

import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class Example {
  public static void main(String... args) {
    WebDriver driver = null;
    try {
      // drvier 설정 - 저는 d드라이브 work 폴더에 있습니다.
      System.setProperty("webdriver.chrome.driver", "d:\\work\\chromedriver.exe");
      // Chrome 드라이버 인스턴스 설정
      driver = new ChromeDriver();
      // 스크립트를 사용하기 위한 캐스팅
      JavascriptExecutor js = (JavascriptExecutor) driver;
      // 블로그 URL로 접속
      driver.get("https://nowonbun.tistory.com");
      // 대기 설정
      driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
      // xpath로 element를 찾는다. 이 xpath는 명월 일지 블로그의 왼쪽 메뉴의 Dev note의 Javascript, Jquery, Css 카테고리다.
      WebElement element = driver.findElement(By.xpath("//*[@id='leftside']/div[2]/ul/li/ul/li[1]/ul/li[6]/a"));
      // 클릭한다. 사실 element.click()로도 클릭이 가능한데 가끔 호환성 에러가 발생하는 경우가 있다.
      js.executeScript("arguments[0].click();", element);
      while (true) {
        try {
          // css selector로 element를 찾는다.
          element = driver.findElement(By.cssSelector("[href^='/626']"));
          // 클릭
          js.executeScript("arguments[0].click();", element);
          // 루프 정지
          break;
        } catch (Throwable e) {
          // 해당 element가 없으면 아래의 다음 페이지 element를 찾는다.
          element = driver.findElement(By.cssSelector(".paging li.active+li > a"));
          // 클릭
          js.executeScript("arguments[0].click();", element);
        }
      }
      // id가 promptEx인 데이터를 찾는다.
      element = driver.findElement(By.xpath("//*[@id='promptEx']"));
      // 버튼은 클릭이 되는데 link 계열은 script로 클릭해야 한다.
      element.click();
      // xpath로 팝업의 dom를 찾는다.
      element = driver.findElement(By.xpath("/html/body/div[6]/div/div/div[2]/div/form/input"));
      // input text에 test의 값을 넣는다.
      element.sendKeys("test");
      // 5초 기다린다.
      Thread.sleep(5000);
      // xpath로 팝업의 dom를 찾는다.
      element = driver.findElement(By.xpath("/html/body/div[6]/div/div/div[2]/div/form/input"));
      // 속성 value를 출력한다.
      System.out.println(element.getAttribute("value"));
      // .article의 글에 p 태그의 속성을 전부 가져온다.
      List<WebElement> elements = driver.findElements(By.cssSelector(".article p"));
      for (WebElement ele : elements) {
        // 속성의 NodeText를 전부 출력한다.
        System.out.println(ele.getText());
      }
    } catch (Throwable e) {
      e.printStackTrace();
    } finally {
      driver.close();
    }
  }
}

이제 소스를 실행해 보겠습니다.

위 소스는 제 블로그를 접속해서 Dev note의 Javascript, Jquery, Css 카테고리의 카테고리를 클릭하고 Bootstrap의 팝업 예제로 가서 팝업 안의 텍스트 박스에 값을 넣습니다.

그리고 마지막에 .article p의 태그를 모두 가져와 콘솔에 출력하는 예제입니다.

제대로 실행이 되네요.


세부적으로 탐색하는 클래스에 대해서 알아보겠습니다.

findElement에서 By클래스의 xpath와 cssSelector를 사용했습니다.

함수명 설명
By.id 요소의 속성 id로 찾는 오브젝트를 찾습니다.
By.className 요소의 속성 class가 포함된 오브젝트를 찾습니다.
By.name 요소의 속성 name로 찾는 오브젝트를 찾습니다.
By.xpath xpath를 이용해서 오브젝트를 찾습니다.
By.linkText 하이퍼 링크의 텍스트로 오브젝트를 찾습니다.(완전 일치) - 탐색이 잘 안됩니다.
By.partialLinkText 하이퍼 링크의 텍스트로 오브젝트를 찾습니다.(포함) - 탐색이 잘 안됩니다.
By.tagName 요소의 태그 이름으로 찾습니다.
By.cssSelector css selector(sizzle)로 오브젝트를 찾습니다.

위 탐색 함수는 findElement를 사용했는데 복수의 경우는 findElements로 검색하면 복수의 요소를 리스트로 취득할 수 있습니다.


그리고 복잡한 웹의 경우, xPath를 구하기 어려운데 이 경우는 브라우저의 개발자 모드로 찾을 수 있습니다.

먼저 개발자 모드의 왼쪽 위를 클릭해서 찾고자 하는 요소를 선택하면 개발자 모드에 태그가 선택이 됩니다.

선택된 태그에서 마우스 오른쪽 클릭을 하면 copy 메뉴가 있는데 그 안에 xpath와 css selector 경로가 나오게 됩니다. 단순히 직접 경로가 나오기는 하지만 그 값을 통해서 약간의 상대 경로(?)로 수정하면 path를 찾을 수 있습니다.


그 외에 selenium에서 자주 사용하는 함수에 대해 소개하겠습니다.

함수명 설명
WebDriver.manage().timeouts().implicitlyWait(시간, TimeUnit) 탐색시 object가 없으면 대기하는 시간.
WebDriver.close() 브라우저를 종료한다.
JavascriptExecutor.executeScript("스크립트", 요소) 해당 페이지에 스크립트를 만들 때 사용합니다. 요소는 필수 파라미터는 아니고 요소가 있으면 요소에 스크립트가 실행되고 없으면 전체 페이지에 스크립트가 움직입니다.
참고, IJavaScriptExecutor는 IWebDriver의 인스턴스를 강제 캐스팅으로 구할 수 있다.
WebDriver.getAttribute("속성") 속성 값을 가져온다.
WebDriver.sendKeys() text의 경우는 값을 넣거나 key값을 넣으면 동작을 지시합니다.
키의 값은 다음 링크를 참조해 주세요.
링크 - https://www.selenium.dev/selenium/docs/api/dotnet/html/T_OpenQA_Selenium_Keys.htm
driver.manage().getCookies() 쿠키 을 가져온다.

그 밖의 API는 아래 링크를 참고해 주세요.

link - https://www.selenium.dev/selenium/docs/api/java/


작성하고 보니 C#이랑 거의 95%이상 소스가 같네요...;;;

링크 - [C#] Selenium을 사용하는 방법


여기까지 Java에서 Selenium을 사용하는 방법에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.