| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- modelcontextprotocol
- gitflow
- mcp
- 네이버 크롤링
- 깃허브
- restful
- mcpserver
- Github action
- 깃플로우
- 회원관리
- 자바스크립트기초
- CRUD
- github
- SQLD
- CI/CD
- springboot크롤링
- 개발자튜토리얼
- springframework
- 자바스크립트
- selenium
- 모던 자바스크립트
- 브랜치관리전략
- springboot 크롤링
- 스프링부트
- SpringBoot
- Nan
- llm연동
- 백엔드개발
- rest api
- spring
- Today
- Total
JUNEee
[Spring Boot] selenium 을 사용한 네이버 플레이스 리뷰 크롤링(2) 본문
selenium을 활용한 네이버 크롤링 2편
삽질의 시간!
자 먼저 크롤링을 수행할 페이지를 찾기 위해 리뷰가 있는 네이버 지도를 들어가 준다(Chrome)
네이버 지도
스타벅스 페이지로 이동
그 다음 리뷰가 있는 페이지로 이동해줄텐데 나는 강남 스타벅스 페이지 에서 삽질을 해볼 생각이다
개발자 도구 열기
먼저 리뷰를 누르고 크롬 브라우저 우측 상단 점 3개 클릭 -> 도구 더보기 -> 개발자 도구 를 눌러 준다
개발자 도구에서 리뷰 요소 찾기
개발자 도구 창에서 좌측 상단에 보시면 페이지 element를 선택할 수 있는 도구가 있는데
클릭한 다음 리뷰를 누르자

개발자 도구에서 리뷰 요소 찾기
그러면 해당 리뷰 글이 어떤 요소에 포함되어 있는지 전반적인 페이지 구조를 확인할 수 있게 된다
페이지 구조 분석
그렇다면 이제 리뷰를 찾았으니까 현재 페이지에서 크롤링을 수행하는 것이 맞을까?
가능은 하겠지만 너무 비효율적이다.. 왜냐하면 리뷰 쪽만 크롤링 할 예정인데 너무 많은 불필요한 요소들이 함께 포함되어 있어 크롤링 과정이 복잡해지기 때문
따라서 우리는 리뷰 부분만을 포함하고 있는 부분을 찾을 생각이다.
먼저 페이지를 슥 한번 훑어보면 리뷰를 포함하고 있는 상위 태그에 entryIframe 이라는 id값을 가지고 있는 iframe이 보인다
iframe은 웹페이지 안에 웹페이지를 불러올 수 있게 하는 기능이다
따라서 구조를 분석해보면 스타벅스 강남R점 의 리뷰가 포함된 상세 페이지는 iframe을 사용하여 페이지 내에 삽입되어 있다는 사실!
삽입되어 있는 상세 페이지의 링크를 찾아 거기서 크롤링을 수행한다면 매우 효율적으로 크롤링을 수행할 수 있게된다
상세 페이지로 이동
삽입된 상세 페이지로 이동해보자
뭔가 확대된(?) 느낌? 이제 여기서부터 크롤링을 시작해볼 예정이다
아까처럼 개발자 도구에서 element 선택 기능을 사용해 댓글 요소를 클릭!

크롤링 시작
구조를 보면 pui__vn15t2 라는 클래스명을 갖는 하위 요소에 a태그 내에 리뷰글이 존재하고 있다 우리는 이 부분을 공략해볼 예정이다
혹시 눈치 챈 사람도 있을 것 같은데 이전 블로그에서 크롤링을 수행 할 메서드의 인자값으로 id 값이 들어간다고 했었고 이는 매장의 고유 코드번호 같은 것이라 이야기 했었다 페이지위에 주소 부분을 자세히 보면 숫자가 보인다
해당 숫자가 바로 스타벅스 강남R점 의 고유 식별자(?) 코드 같은 것이다
이제 우리는 조회를 원하는 매장의 식별자 코드만 알게 된다면 해당 매장을 특정하여 리뷰와 같은 데이터를 가지고 올 수 있게 될 것이다!
크롤링 시작:메서드 구현
다시 스프링으로 돌아가서 이전 블로그에서 만들었던 service클래스에 들어가 보자
accessNaverPlaceReview 라는 이름의 메서드를 구현해볼 것이다
코드는 아래와 같다값을 json형태로 반환해야 하기 때문에 데이터를 담을 dto클래스도 만들어 준다간단한 테스트 api도 필요하므로 controller클래스도 만들어 준다자세한 설명은 주석으로 처리했다@RestController public class Controller { @Autowired Service service; @GetMapping("/test/{id}") public ResponseEntity<?> test(@PathVariable String id) { return service.accessNaverPlaceReview(id); } }@Getter @Setter public class ReviewDto { private String cafeName; //카페이름 private String status; //현재 영업중인지 여부 private List<?> reviews; //리뷰들 }@Autowired private WebDriver driver; //웹 브라우저를 제어하기 위한 객체 private List<String> reviews_str; //크롤링한 리뷰들을(문자열로 변환된) 저장하는 리스트 객체 public ResponseEntity<?> accessNaverPlaceReview(String id) { try { ReviewDto reviewDto = new ReviewDto(); String url = "https://pcmap.place.naver.com/restaurant/" + id + "/review/visitor?additionalHeight=76&from=map&fromPanelNum=1&locale=ko&svcName=map_pcv5×tamp=202503291343"; //네이버 지도 리뷰 링크 String url2 = "https://pcmap.place.naver.com/restaurant/" + id + "/home?additionalHeight=76&from=map&fromPanelNum=1&locale=ko&svcName=map_pcv5×tamp=202503291343"; //네이버 지도 홈 링크 driver.get(url); //네이버 지도 리뷰 페이지로 이동 List<WebElement> reviews = driver.findElements( //리뷰 크롤링 By.cssSelector("div.pui__vn15t2 a") ); reviews_str = reviews.stream() .map(WebElement::getText) .filter(text -> !text.equals("더보기")) .collect(Collectors.toList()); //더보기 제거 String name = driver.findElement(By.className("bh9OH")).getText(); //식당 이름 크롤링 driver.get(url2); //네이버 지도 홈으로 이동 String status = driver.findElement(By.cssSelector(".A_cdD em")).getText(); //매장 이름 크롤링 reviewDto.setCafeName(name); reviewDto.setStatus(status); reviewDto.setReviews(reviews_str); return ResponseEntity.ok().body(reviewDto); } catch (Exception e) { return ResponseEntity.badRequest().body("error"); } }
- 진짜 끝
이제 프로젝트를 빌드한 뒤 postman이나 또는 기타 api테스트 프로그램을 사용해 테스트를 해보자
/test/1086067689 api로 요청을 했고 결과는?!
이렇게 잘 받아오는 것을 확인할 수 있다
1편 도입부분에 한번 설명 했지만, 블로그에서 설명한 대로 진행하면 pui__vn15t2 라는 요소를 찾지 못했다고 나올 것이다
네이버는 기본적으로 크롤링을 허용하지 않고 있기 때문에 selenium 이 에러 페이지에 접근하게 되어 거기서 요소를 찾으려고 하기 때문이다
따라서 selenium을 정상적으로 접속하게 하려면 약간의 우회가 필요한데, 이는 구글링 좀만 해봐도 방법이 나온다
'BE > 스프링' 카테고리의 다른 글
| [Spring Boot] rest api 스프링부트 회원관리 기능 구현하기! (CRUD) (1) | 2025.05.29 |
|---|---|
| [Spring Boot] REST Api 란 무엇일까? (1) | 2025.05.22 |
| [Spring Boot] Github Actions 를 활용한 CI/CD 파이프라인 구축(개념) (0) | 2025.04.17 |
| [Spring Boot] MCP(Model Context Protocol) 기본 개념 및 테스트(1) (0) | 2025.04.04 |
| [Spring Boot] selenium 을 사용한 네이버 플레이스 리뷰 크롤링(1) (4) | 2025.03.29 |