-
Jsoup 웹 크롤링 , 스프링 부트 구글 지도 위도 경도 가져오기Project/NomadWorker 2022. 8. 11. 16:21
제1회 한국외대 썸머 해커톤 우수상을 받은 프로젝트 "노마드 워커 "의 기능을 개발 하는데 필요했던 기능 구현의 관한 글 입니다.
깃허브 : https://github.com/HUFSummer-Hackathon/Server
특정 사이트에서 위도 경도를 주소마다 변환해서 가져오고 그것을 다시 db 에 넣는 수고 스러움을 덜고 싶었다.
목표:
특정 장소의 위도 경도 가져오기 , 구글 맵 api 사용 안하기.
구글지도 위도 경도 가져오기.
Point
가능하면 웹사이트에서 response body에 포함된 data 를 가져오는 방식 보다 url 쿼리 response 를 가져오는 것을 고려 한다.
사용 기술 :
Spring boot ,JPA , Hibernate
build.graddle에 jsoup depndencie 추가. 웹 스파이더링을 위한 라이브러리이다.
implementation 'org.jsoup:jsoup:1.15.2'
+ google devtoolkit : 크롬창에서 f12 를 누르면 페이지의 구성요소를 알 수 가 있다.
서문 & 문제점:
스프링 프레임워크 라이브러리 jsoup 을 이용하여 주소 좌표변환 웹사이트에 원하는 검색 결과를 입력 하고 response 를 받는 작업을 해본다.
1.
!!! Jsoup 은 동적 웹페이지의 클롤링을 지원하지 않는다 , 즉 html <input 을 이용하여 만든 form 에서
.버.튼.을 클,릭! 을 하여 원하는 정보를 가져 오는것이 불가능 하다. 만약 본인이 버튼을 클릭하여 나오는 데이터를 원한다 하면
Selinium 을 검색하여 사용해보길 권한다.
2.
요즘 웹사이트의 경우 , 서버에 요청한 request 의 대한 response 를 잘 안보이게 숨기는 경우도 많고 (보안상의 이유로),
Jsoup 을 단독으로 이용을 하여 response 를 원하는대로 받아오는 것이 사이트마다 다르다.
Tip : 다음 사진의 나오는 것과 같이 구글 크롬 개발자 도구 네트워크에 있는 해더의 정보들을 확인해주자
---------------------------------------구글 개발자도구로 본 응답 ------------------------------------
어떻게 하지 고민을 하다가.
구글 맵을 사용 하는 것을 생각했다. (정말 문득 구글 크롤링을 하자라고 생각이 듬)
1. 구글 맵 api
: 비용이 든다 기각.
2. 구글 맵 검색창의 원하는장소 입력이후 잠깐 나오는 url 주소를 이용한다.
: 이걸로 가자
[분석1]
구글의 url 주소 "https://www.google.co.kr/maps/search/"
/뒤의 원하는 검색 조건을 입력을 하고 검색을 하게 되면 url주소가 크롬창 기준으로 변환한다.
검색 후 url
"https://www.google.co.kr/maps/place/%(~생략~)d37.5086551!4d127.0393959?hl=ko"
37.5086 , 127.039 -> 위도 경도 좌표가 url 에 포함이 되어 있다.
처음 시도한 방식처럼 웹사이트에서 response data 을 가져오는 방식이 아닌 검색 결과의 따른 url redirection 의 정보를 가져오는 것이 개발측면에서 더 빠를것 같다 라는 생각을 했다.
[분석2]
구글 개발자 도구를 켜서 코드를 살펴본 결과 , <head> 테그 안 <meta content= , 에 위도 경도 좌표가 나오는 것을 확인 했다.
[구현]
코드 짜자.
1.DTo
package hackathon.nomadworker.dto; import lombok.AllArgsConstructor; import lombok.Data; public class DownloadDtos { @Data @AllArgsConstructor public static class ResultResponse<T> { private String message; private int status; private T data; } @Data public static class DownloadRequest { private String address; } @Data public static class DownloadResponse { private float lati; private float longi; public DownloadResponse(float lati, float longi) { this.lati = lati; this.longi = longi; } } }
2. url 속 정보 추출
package .....api; import .....dto.DownloadDtos.*; import lombok.Data; import lombok.RequiredArgsConstructor; import org.jsoup.Connection.*; import org.jsoup.select.Elements; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import javax.validation.Valid; import java.io.IOException; @RequiredArgsConstructor @RestController public class PlaceDownloadApiController { @PostMapping(value="/api/download" , produces = "application/json;charset=UTF-8") public ResultResponse userPost(@Valid @RequestBody DownloadRequest request) { String url = "https://www.google.co.kr/maps/search/"; String searchaddr = request.getAddress(); try { Response res = Jsoup.connect(url+request.getAddress()).followRedirects(true).execute(); Document doc = res.parse(); Elements metaTags = doc.getElementsByTag("meta"); String linkOrigin = metaTags.get(10).attr("content"); int s = linkOrigin.indexOf("="); int l = linkOrigin.indexOf("%"); String longi =linkOrigin.substring(s+1,l); s = linkOrigin.indexOf("C"); l = linkOrigin.indexOf("&"); String lati =linkOrigin.substring(s+1,l); return new ResultResponse("ok",200,longi +":"+lati); } catch (IOException e) { throw new RuntimeException(e); } } }
- 주요 코드 설명:
1. 주소 창 redirects 를 따라가게 connect 을 해준다. -> followRedirects(true)
Response res = Jsoup.connect(url+request.getAddress()).followRedirects(true).execute();
2. 파싱 . f12 헤더를 보면 meta tag , content 라는 부분에 우리가 원하는 위도 경도 좌표가 있다 .
Document doc = res.parse();
Elements metaTags = doc.getElementsByTag("meta");
String linkOrigin = metaTags.get(10).attr("content");결과 : Request body "address" 에 구글 지도에서 검색했던 것 과 같은 키워드를 입력해본다.
이후 성능 개선 필요한점 .
1.
구글 맵에서 여러가지의 장소를 결과로 보여주면 meta data content 10 번째에 우리가 원하는 위도 경도 좌표가 없다.
2. 의존성 문제 ,,, 구글에서 정보를 제공하는 방식이 바귀면 , 코드가 안돌아 갈 수 도 있다.
'Project > NomadWorker' 카테고리의 다른 글
자바 스프링 mysql 위치좌표(위도 경도) 정리, POINT DATA (0) 2022.07.22