구글 플레이스토어 앱 리뷰를 수집하여, 수집한 리뷰데이터 KOMORAN 라이브러리를 통해 명사만 추출하여 해당 앱들의 키워드를 worldCloud로 뿌려주는 기능을 개발하게 되었다.
해당 기능을 개발하면서 겪었던 오류나 개발하면서 알게되었던 내용을 정리해보고자 한다.
1. 셀레니움 설치 전 Chrome 버전 확인
: Chrome 오른쪽 상단 ... → 설정 → Chrome 정보에서 버전 확인
2. Chrome Driver 설치하기
ChromeDriver 홈페이지에서 위에서 확인한 자신의 Chrome버전과 맞는 Driver를 설치해줘야 한다.
3. pom.xml에 라이브러리 추가 (url : https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java)
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
4. 구글 플레이스토어 앱 리뷰 크롤링 하기
내가 수집하고자 하는 데이터는 다음과 같았다. ( 사용자 이름, 리뷰내용, 별점, 좋아요 수, 작성일자 )
구글플레이 스토어에서 앱에 대한 리뷰가 최대 3개밖에 보이지 않아서, "모든 리뷰 보기" 버튼 클릭하는 코드를 추가해야했다.
F12(개발자 도구)를 누르면 해당 페이지의 HTML 코드를 볼 수 있어서 웹 페이지가 어떻게 구성되어 있는지 쉽게 파악할 수 있다.
4-1) 구글플레이스토어 웹 페이지 띄우기
public void getReivew() throws InterruptedException {
System.setProperty(chromeDriverName, chromeDrvierPath);
//크롬 드라이버 셋팅 (드라이버 설치한 경로 입력)
ChromeOptions options = new ChromeOptions();
options.addArguments("--no-sandbox")
.addArguments("--disable-dev-shm-usage")
.addArguments("--disable-blink-features=AutomationControlled");
driver = new ChromeDriver(options);
driver.get(url);
}
4-2) 리뷰 모두 보기 버튼을 클릭 했을 때, 동적 페이지 형식으로 되어있어서 모든 리뷰를 가져오기 위해서는 스크롤을 통해 맨 아래로 내리는 작업을 해줘야했다.
scrollTo 함수를 사용했을 때, 리뷰 모달창이 아닌 뒤에 있는 페이지가 아래로 내려가 포커싱을 모달창에 잡아주는 과정에서 많은 시간을 소요했다.😂
WebElement prev_element = null ;
while(true) {
WebElement element = driver.findElement(By.xpath("//*[@id=\"yDmH0d\"]/div[4]/div[2]/div/div/div/div/div[2]/div/div[2]/*[last()]"));
if(element.equals(prev_element)) break;
JavascriptExecutor.executeScript("arguments[0].scrollIntoView(true);", element);
Thread.sleep(4000);
prev_element = element;
}
i) 로딩된 리뷰 모달창에 사용자의 마지막 리뷰에 해당하는 xpath를 웹페이지에서 가져온 뒤, 해당 element 값이 prev_element 값과 동일하다면 웹 페이지에 모든 리뷰를 로딩했음을 의미하므로 종료
ii) JacascriptExecutor 를 이용해 해당 element 위치까지 스크롤를 내려주는 과정을 반복
[위 소스코드 결과]
4-3) 앱 리뷰 데이터 파싱해서, 내가 원하는 데이터로 가공해 적재하기
public void dataParsing(WebDriver driver, String appName) {
List<WebElement> list = driver.findElements(By.className("RHo1pe"));
DataMap map;
try {
for(int i=0;i<list.size();i++) {
String[] str = list.get(i).getText().split("\\n");
map = new DataMap();
map.put("appName", appName);
map.put("userName", str[0]);
map.put("contents", str[3]);
String score = list.get(i).findElement(By.xpath("//*[@id=\"yDmH0d\"]/div[4]/div[2]/div/div/div/div/div[2]/div/div[2]/div[38]/header/div[2]/div")).getAttribute("aria-label")
.replaceAll("[^0-9]", "");
map.put("score", Integer.parseInt(score.substring(score.length()-1)));
String thumbsUp = str[4].replaceAll("[^0-9]", "");
thumbsUp = thumbsUp.length()==0 ? "0" : thumbsUp;
map.put("thumbsUp", Integer.parseInt(thumbsUp));
map.put("cretDt", compareFormat.parse(str[2]));
googlePlayStoreReviewMapper.insertReviewData(map);
}
} catch (ParseException e) {
// catch
}
}
[앱 리뷰 데이터 파싱 결과]
## 2023-06-15 추가
1) 매번 모든 리뷰를 파싱하면 비효율 적이므로, 최신 순으로 정렬 후 앱에 해당하는 마지막 리뷰일자를 찾아 그 이후 날짜에 해당하는 리뷰만 파싱해 올 수 있도록 코드를 수정했다.😊
'정리 > Java' 카테고리의 다른 글
ListIterator (0) | 2021.10.20 |
---|