👉selenium
: 웹사이트를 테스트하기 위한 도구로, 브라우저 동작을 자동화 할 수 있다. 셀레니움을 이용하는 웹크롤링 방식은 프로그래밍으로 브라우저 동작을 제어해 마치 사람이 이용하는 것처럼 웹페이지를 요청하고 응답을 받아올 수 있다.
👉설치 및 준비
:크롬 웹 드라이브 필요(버전 확인 후 버전에 맞는 드라이버 다운 - python으로 붙여넣기 (셀레니움을 할 파이썬 파일과 경로가 같아야 함))
driver = webdriver.Chrome('chromedriver') #크롬 드라이버 사용
driver.get(url)
time.sleep(5)
for i in range(10):
try:
btn_more = driver.find_element_by_css_selector("#foodstar-front-location-curation-more-self > div > button")
btn_more.click()
time.sleep(5)
except NoSuchElementException:
break
# 스크래핑 페이지의 맛집 목록은 16개가 기본으로 떠있는데 더 많은 정보를 가져오기 위해서
# 사람이 누르는 것 처럼 더보기 버튼을 누르게 함(선택자 사용) << 셀레니움은 이런 조작을 가능하게 함!
# 5초의 간격을 두고 10초 반복 (약 160개 가량의 정보를 가져올 수 있게 하는 구문)
req = driver.page_source
driver.quit()
soup = BeautifluSoup(req, 'html.parser')
places = soup.select("ul.restaurant_list > div > div > li > div > a") # 정보를 가져올 부분의 전체 선택자
for palce in places:
title = place.select_one("해당선택자").text
address = place.select_one("해당선택자").text
category = place.select_one("해당선택자").text
show, episode = place.select_one("해당선택자").text.rsplit(" ",1)
# rsplit : split 함수와 비슷한 용도, 차이점은 rsplit()은 뒤에서부터 스트링을 나눈다
👉네이버오픈API / Maps Docs / web dynamic map 사용방법
/ Geocoding사용방법
원하는 API서비스를 선택하고, 키를 발급받는다.
👉 ex) geocode
headers = {
"X-NCP-APIGW-API-KEY-ID": "발급받은ID",
"X-NCP-APIGW-API-KEY": "발급받은 시크릿 ID"
}
r = requests.get(f"https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query={address}", headers=headers
response = r.json()
if response["status"] == "OK";
if len(response["addresses"]) > 0:
x = float(response["addresses"][0]["x"]
y = float(response["addresses"][0]["y"]
<head>
<script type="text/javascript"
src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId={발급ID}&submodules=geocoder"></script>
<script>
let y_cen = 37.4981125 // //전역변수로 지정 (모든 함수에서 사용 가능하게 함)
let x_cen = 127.0379399 // long
let map;
let markers = [];
let infowindows = [];
$(document).ready(function () { // 페이지가 실행되자마자 지도를 띄우기 위해 ready(functon() 에 넣음)
map = new naver.maps.Map('map', {
center: new naver.maps.LatLng(y_cen, x_cen),
zoom: 12,
zoomControl: true,
zoomControlOptions: {
style: naver.maps.ZoomControlStyle.SMALL,
position: naver.maps.Position.TOP_RIGHT
}
});
get_matjips()
})
</script>
</head>
function get_matjips(){
$.ajax({
type: "GET",
url: '/matjip',
data: {},
success: function (response) {
let matjips = response["matjip_list"] // matjips에 DB에 저장되어 있던, 맛집 정보를 모두 저장 (리스트)
for (let i = 0; i < matjips.length; i++) {
let matjip = matjips[i]
console.log(matjip)
make_card(i, matjip); // matjips 리스트를 각 함수에 매개변수로 넣어서 사용
let marker = make_marker(matjip);
add_info(i, marker, matjip)
}
}
}
function make_marker(matjip){
let marker = new naver.map.Marker({
position : new naver.maps.Lating(matjip["mapy"], matjip["mapx"]),
map : map //어느 맵에 표시될 것인가! (맨 위에 설정했던 map 불러온거임)
});
markers.push(marker)
// 가장 상단 전역변수에 지정한 let markers = []에 불러온 마커 정보들이 입력되어 들어감
return marker
// get_matjips의 for문 내에서 불려지고 있기 때문에, for문이 도는 횟수만큼 marker도 return 됨
}
function add_info(i, marker, matjip){
let html_temp = `<div class="iw-inner">
<h5>${matjip['title']}</h5>
<p>${matjip['address']}
</div>`;
let infowindow = new naver.maps.InfoWindows({
content: html_temp,
maxWidth: 200,
backgroundColor: "#fff",
borderColor: "#888",
borderWidth: 2,
anchorSize: new naver.maps.Size(15, 15),
anchorSkew: true,
anchorColor: "#fff",
pixelOffset: new naver.maps.Point(10, -10)
});
infowindows.push(infowindow) // 마찬가지로 위에 let infowindoww = [] 에 리스트로 저장
naver.maps.Event.addListener(marker, "click", function(e) { //마커를 클릭했을때
if(infowindow.getMap()){ // infowindow가 맵에 떠있으면
infowindow.close(); //끄고
}else{ //그게아니라면
infowindow.open(map,marker); //켜주세요
map.setCenter(infowindow.position)
$("#matjip-box").animate({
scrollTop:
$("#matjip-box").get(0).scrollTop + $(`#card-${i}`).position().top
}, 2000);
}
});
}