2021. 1. 18. 10:28ㆍComputer Science/Backend
JAVA Selenium
데이터 크롤링을 하게됐다. 자바를 메인언어로 바꾸겠다고 마음 먹은지 6개월정도 지났나 이제 좀 익숙해져 가고 있다. 두려움을 떨쳤다는 것 만으로도 스스로 기특하다고 생각하고 있다. 파이썬에서 자바로 언어를 바꿀 때 가장 답답한 부분은 함수형 사고방식에서 OOP형 사고방식으로 바꾸는 거였다. 뭐든 모르면 쫄기 마련인데, 하다보면 사실 몰랐을 뿐 어려운 건 아니었다는 생각을 하게 된다. 셀레니움 쓰다보면 자주 맞닥뜨리는 에러랑 간단한 해결법이다. 이런 글이라도 도움 되는 사람이 있겠지.
1. NoSuchElementException
셀레니움을 쓰다보면 제일 많이 보이는 에러다. 그런 엘리먼트는 없어~ 이런 느낌이다. 기본적으로 셀레니움은 다음 코드를 가장 많이 사용한다.
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
// WebDriver
private WebDriver webDriver;
// Crawl by xpath
WebElement test = webDriver.findElement(By.xpath("//*[@id=\"main_contents\"]/div[4]/div[1]/a[2]"));
// Crawl by Selector
WebElement test2 = webDriver.findElement(By.cssSelector("#container > div:nth-child(4) > form > div.box_detail_point"));
중간에 뭘 많이 생략했지만 어쨌든 대충 이런 느낌이다. NoSuchElementException이 나타나는 경우는 xpath나 CssSelector를 잘못 입력해줬다는 의미다. 나같은 경우는 상품 리스트의 상세페이지에 일일이 접근해서 데이터를 가져와야 되는 상황이었다. 상세페이지마다 일정한 xpath에 일정한 값이 할당 돼 있어야 했는데, 값이 미묘하게 다른 경우 엄한 부분이 크롤링 되거나 해당 에러가 발생했다. 내가 해결한 방법은 그냥 try . . . catch문으로 해결해줬다. div값 하나가 다르다거나 그런 문제였기 때문이다.
try {
WebElement isub = webDriver.findElement(By.xpath("/html/body/div[2]/div[1]"));
temp.put("isub", isub.getText());
} catch (NoSuchElementExceiption se){
System.out.println("아래 상품에서 예외처리 발생 ");
WebElement isub = webDriver.findElement(By.xpath("/html/body/div[3]/div[1]"));
temp.put("isub", isub.getText());
}
temp는 무시해도 된다. 그냥 HashMap에 add하는 부분.. xpath값을 보면 div[2]랑 div[3]부분이 다른게 보일텐데 이런 방법으로 해결했다.
2. ElementClickInterceptedException
이건 테스트중 클릭을 수행할 때 발생하는 에러다. 처음에 시도했던 방법은
WebElement clickUnderTen = webDriver.findElement(By.xpath("//*[@id=\"main_contents\"]/div[4]/div[1]"));
clickUnderTen.click();
이거였는데
WebElement clickUnderTen = webDriver.findElement(By.xpath("//*[@id=\"main_contents\"]/div[4]/div[1]"));
clickUnderTen.sendKeys(Keys.ENTER);
click() -> sendKeys(Keys.ENTER)로 바꿔주니까 해결됐다. click()과 sendKeys()의 차이점은 다음과 같다.
- sendKeys() : 특정 값을 입력할 수 있는 input Box를 활용할 때 쓴다. text box를 엔터할 때 사용한다.
- click() : 링크를 클릭하고 페이지 로드가 완료될 때까지 기다린 후 다음 명령을 진행한다.
'Computer Science > Backend' 카테고리의 다른 글
mac에 하둡(3.3.0) 설치하기 (0) | 2021.06.06 |
---|---|
Spring Boot와 sqlite3 연동, JPA, Hibernate, SQLDialect (3) | 2021.05.04 |
Spark로 HDFS 데이터 활용하기 (+ pandas, time range filter) (2) | 2020.07.22 |
[Linux] screen 명령어로 백그라운드 프로세스 띄우기 (0) | 2020.07.13 |
[Kafka] 카프카 주요 개념 정리 (2) | 2020.05.30 |