[JAVA 4#] [Web Automation 4#] Controlling STEEMIT web pages with Selenium #2 Find Elements [KR]

in #kr5 years ago

redsjavahouse1591357_1280.jpg
image source: pixabay


Selenium이 기본 제공하는 기능들을 몇번에 나눠서 정리해본다. 웹페이지를 다루려면 제일 먼저 해야 하는 것이 바로 웹페이지내의 엘리멘트를 찾아내는 것이다. 웹페이지에서 개발자도구를 열어보면 이 페이지의 html 코드를 볼 수 있는데 이를 통해 엘리멘트를 확인할 수 있다. 👇
image.png

그럼 코드로 다시 돌아와서 Selenium으로 작성해 보자. Selenium 에서 기본적으로 findElement, findElements라는 두 메서드를 제공하는데 전자는 WebElement 객체를 리터하고, 후자는 List<WebElement>를 리턴한다.
인자는 모두 Selenium의 By 클래스이다. (By 클래스는 셀레늄에서 상당히 중요한 클래스이다.) 자동완성(ctrl + space)로 지원하는 메서드를 확인해 보자. 👇
image.png

다양한 메서드를 지원하는데 하나씩 알아본다.

  1. By.className - 웹 엘리멘트(이하 태그라고 한다.) 에 각각 속성이 있는데 이중에서 제일 자주 쓰이는 속성이 바로 class 속성인데 이 속성값으로 태그를 찾아 리턴한다.
  2. By.cssSelector - 웹 페이지의 html 트리 구조는 복잡한만큼 보다 쉽게 태그를 수정하고 컨트롤하는 방법 또한 다양하다. 그 방법중 하나인 css Selector로 태그를 찾아 리턴한다. css Selector 문법은 여기를 참고한다.
  3. By.id - class와 동일하게 태그 속성이고 값은 유일한 값이다. 유일한 값이므로 가장 쉽게 태그를 찾을 수 있지만 한계 또한 있다. 많은 웹개발자들은 id값을 사용하지 않는 것 같다. class가 있지만 id가 없는 경우가 대부분이기때문이다. 게다가 id값은 가변값으로 사용될 때도 많아서 개인적으로 이 방법은 잘 쓰지 않는다.
  4. By.linkText - 링크가 걸려있는 a태그의 텍스트 값과 완전 매칭되는 태그를 찾아 리턴한다.
  5. By.partialLinkText - 위와 비슷하지만 텍스트값이 부분 매칭이어도 태그를 찾을 수 있다.
  6. By.name - 위 class, id와 동일하게 태그 속성이다. name속성 값으로 태그를 찾아 반환한다.
  7. By.tagName - 말 그대로 태그 이름으로 찾아서 반환한다. 웹 페이지에 같은 이름으로 된 태그가 많아 이 방법은 잘 사용하는 방법은 아닌 것 같다.
  8. By.xpath - cssSelector 처럼 태그를 찾는 방법중 하나이다. cssSelector와 마찬가지로 복잡한 문법이 있는데 손에 익히면 가장 사용하기 좋은 방법이다. 참고로 나는 주로 이 방법을 사용한다. 이유는 xpath 문법에는 ancestor, descendant, following-sibling, preceding-sibling 등 기워드가 다양하고, text(), contains() 등 메서드도 지원하고 있어 태그를 찾는데 자유도가 매우 높은데 있다.

image.png
👆 하나씩 사용해 보니 대충 요런 느낌이다. 상황에 맞게 사용하면 될 것 같다.

image.png
그럼 이제 findElement 부가적인 메서드들을 알아보자. findElement() 메서드 뒤에 .으로 부가 메서드를 추가할 수 있다. 자동완성으로 보면 아래와 같은데 WebElement 인터페이스에 속한 메서드만 알아보도록 한다.

  1. clear() - 불러온 태그가 입력박스일 경우 입력된 텍스트를 지워주는 메서드이다.
  2. click() - 이름 그대로 태그를 클릭한다. 단, 해당 태그가 화면에 보여야 하고 길이,높이가 0보다 커야한다.
  3. findElement()/findElements() - findElement()로 태그를 찾은 후 연속으로 같은 메서드를 호출하여 자식 메서드를 찾을 수도 있다. 태그 트리가 복잡하여 여러번 나눠서 최종 태그를 찾아야 할 경우 자주 사용된다. (아래 예제에서도 사용된다.)
  4. getAttribute() - 태그의 속성값을 반환한다. 인자는 class, id, name 과 같은 속성명이다.
  5. getCssValue() - 태그의 css 속성을 불러온다. 인자에 css 속성명 예를 들면 color를 넣어서 호출하면 그 태그의 색상값을 반환한다.
  6. getLocation - 태그의 위치를 반환한다. 부가 메서드에는 getX(), getY()등이 포함된다. (똑같은 페이지 태그라도 할지라도 모니터 해상도에 따라 그 위치가 다를 수 있어 자주 사용하지는 않는다.)
  7. getRect() - 태그의 위치와 size를 반환한다.
  8. getSize() - 태그의 size를 반환한다. 부가 메서드에는 getHeight(),getWidth() 등이 있다.
  9. getTagName() - 태그이름을 반환한다.
  10. getText() - 태그내에 포함된 텍스트를 반환한다. (예: 태그가 <a>로그인</a>일 경우 '로그인'을 반환한다.)
  11. isDisplayed() - 태그가 화면에 보이는지 참,거짓을 반환한다. 태그가 웹페이지에 있지만 표시되지 않는 경우가 많기때문에 이 메서드로 분기처리하여 사용된다.
  12. isEnabled() - 태그가 활성화되었는지 참, 거짓을 반환한다.
  13. isSelected() - 체크박스, 라디오 박스, 드롭다운 메뉴에서 옵션이 선택되었는지 참,거짓을 반환한다.
  14. sendKeys() - 태그에 텍스트를 입력할 때 사용된다. 키보드로 입력할 수 있는 모든 key를 입력할 수 있다. 인자는 CharSequence... 객체이고 가변인자이다. 제일 중요한 메서드중 하나로 다음시간에 자세히 다루도록 한다.
  15. submit() - 태그가 만약 form 혹은 form에 속해 있을 경우 서버에 submit한다. 만약 전송 후 페이지가 변경 될 경우 변경될 때까지 기다린다. (#좋은기능이었네#몰랐...)

여기까지 findElement의 부가 메서드이고, findElements()는 JAVA의 List 객체이므로 다루지 않겠다. List의 기본적인 메서드가 포함된다.


그럼 findElement, findElements 두 메서드로 steemit 대세글 페이지에서 글 목록을 불러온 후 글 제목과 저자를 불러와서 콘솔에 출력해 보자.

package com.steem.webatuo;

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

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

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("steemit.com/@june0620/feed");
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        
        List<WebElement> list = driver.findElements(By.xpath("//div[@id='posts_list']/ul/li"));
        for(WebElement post : list) {
            String title = post.findElement(By.xpath("descendant::h2/a")).getText();
            String author = post.findElement(By.xpath("descendant::span[@class='user__name']")).getText();
            System.out.println(author + "님의 글: " + title);
        }
        driver.quit();
    }

}

영상:

Sort:  

帅哥/美女!快来使用超级好用的steemit客户端---Partiko,这个可是我们华人团队开发的哦。感谢支持。