이번 3주차 수업은 맛집 지도 만들기!
이번에는 말로만 듣던 Open Api를 사용해볼 수 있는 기회가 생겼다!! 하지만 또 새로운걸 배운다는건
쉽지많은 않아 개발일지를 쓰면서 복습 필수!
※ 완성된 프로젝트 모습
일반적인 네이버,카카오 지도 등에서 할 수 있는 기본적인 기능들을 구성하고 있고,
위치정보, 맛집정보, 즐겨찾기 등등
이렇게 만들어본것처럼 Api 사용법만 알 수 있으면 다른 Api를 사용해서 보다 많은 정보들로
웹 서비스, 앱 서비스를 만들 수 있을 것같은 좋은 생각이 드는 강의 였던것같다!
이번 주차에서 가장중요한 점은 역시 " 셀레니움을 통한 웹 스크래핑"
이전 강의에서 배운 크롤링의 단점을 보완할 수 있는 아주 좋은 녀석인것같음!
※ 셀레니움 적용 코드
from bs4 import BeautifulSoup
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome('./chromedriver') # 드라이버를 실행합니다.
url = "<https://www.melon.com/chart/day/index.htm>"
# headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
# data = requests.get(url, headers=headers)
driver.get(url) # 드라이버에 해당 url의 웹페이지를 띄웁니다.
sleep(5) # 페이지가 로딩되는 동안 5초 간 기다립니다.
req = driver.page_source # html 정보를 가져옵니다.
driver.quit() # 정보를 가져왔으므로 드라이버는 꺼줍니다.
# soup = BeautifulSoup(data.text, 'html.parser')
soup = BeautifulSoup(req, 'html.parser') # 가져온 정보를 beautifulsoup으로 파싱해줍니다.
songs = soup.select("#frm > div > table > tbody > tr")
print(len(songs))
for song in songs:
title = song.select_one("td > div > div.wrap_song_info > div.rank01 > span > a").text artist = song.select_one("td > div > div.wrap_song_info > div.rank02 > span > a").text
likes = song.select_one("td > div > button.like > span.cnt").text
print(title, artist, likes)
→ 셀레니움 기본 셋팅 코드로 알아두면 좋을것같다! 설명을 잘해주시니 이해하기 쉽다.
* 셀레니움의 중요 스킬
1. 원하지 않는 정보 지우기
likes_tag = song.select_one("td > div > button.like > span.cnt")
likes_tag.span.decompose() # span 태그 없애기
likes = likes_tag.text.strip() # 텍스트화한 후 앞뒤로 빈 칸 지우기
2. 검색 시 스크롤 내리기!! (네이버 이미지 검색창 예시 코드 참고)
from bs4 import BeautifulSoup
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome('./chromedriver')
url = "https://search.naver.com/search.naver?where=image&sm=tab_jum&query=%EC%95%84%EC%9D%B4%EC%9C%A0"
driver.get(url)
sleep(3)
req = driver.page_source driver.quit()
soup = BeautifulSoup(req, 'html.parser')
images = soup.select(".tile_item._item ._image._listImage")
print(len(images))
for image in images:
src = image["src"]
print(src)
※ 1000픽셀 만큼 내리기
driver.execute_script("window.scrollTo(0, 1000)") # 1000픽셀만큼 내리기
※ 맨밑까지 내리기
sleep(1)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(10)
위의 내용들은 알고있으면 앞으로 스크래핑을 할때 유용하게 사용할 수 있을것같다.
이제 본격적으로 네이버지도 Api 사용을 해보자!!!
신청 및 정보에 대한 자세한 내용은 강의자료를 참고하자
1. 맛집 지도에 필수 스킬
- 확대/축소 버튼
let map = new naver.maps.Map('map', {
center: new naver.maps.LatLng(37.4981125, 127.0379399),
zoom: 10,
zoomControl: true,
zoomControlOptions: {
style: naver.maps.ZoomControlStyle.SMALL,
position: naver.maps.Position.TOP_RIGHT }
});
- 마커 띄우기
let marker = new naver.maps.Marker({
position: new naver.maps.LatLng(37.4981125, 127.0379399),
map: map
});
- 마커 이미지 바꾸기
let marker = new naver.maps.Marker({
position: new naver.maps.LatLng(37.4981125, 127.0379399),
map: map,
icon: "{{ url_for('static', filename='rtan_heart.png') }}"
});
- 정보창 띄우고 닫기
※ infowindow 만들고 열기
let infowindow = new naver.maps.InfoWindow({
content: `<div style="width: 50px;height: 20px;text-align: center"><h5>안녕!</h5></div>`,
});
infowindow.open(map, marker);
※ infowindow 닫기
infowindow.close();
※ 마커를 누를때마다 infowindow 여닫기
naver.maps.Event.addListener(marker, "click", function () {
console.log(infowindow.getMap()); // 정보창이 열려있을 때는 연결된 지도를 반환하고 닫혀있을 때는 null을 반환
if (infowindow.getMap()) { infowindow.close();
} else {
infowindow.open(map, marker);
}
});
※ 맛집지도만들기 프로젝트 순서
1. API설계 및 프로젝트 준비( Client ID 필수로 넣어야한다, API 사용을 위함)
2. 맛집정보 스크래핑 (셀레니움 사용)
- 셀레니움 기본 셋팅 코드는 "scraping.py참고"
- ㉮스크래핑 하려고하는 카드 선택 → ㉯각각의 식당의 이름, 주소, 카테코리 등등 선택
ex)
㉮ places = soup.select("ul.restaurant_list > div > div > li > div > a")
㉯ for place in places:
title = place.select_one("strong.box_module_title").text
사실 처음에 내가 스크래핑 하려는 정보를 찾는것도 힘들지만 개발자콘솔에서 설렉트 기능을 하면 그나마 쉽게 찾을 수 있다!
3. 맛집정보 좌표로 변환하기 (geocoding Api 참고)
- Geocoding 연결하기 (클라이언드 아이디, 시크릿 키를 필수로 입력해야한다.)
- 결과 출력하기 (scraping.py참고)
4. 맛집정보 DB에 저장하기 (여러페이지 스크래핑 하기)
- 최대한 많은 DB를 확보하기위해 하단 "더보기" 버튼을 반복적으로 눌러서 스크래핑 하는게 포인트!!
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
5. 웹사이트 모습 만들기 (DB에서 맛집정보 가져오기. 각 맛집별 카드 만들기)
- 웹사이트 모습을 만드는것은 디자인을 참고
- 서버에서는 DB에 스캐래핑하여 저장된 정보들을 받아와야한다. (app.py)
- 서버에서 받아온 정보들을 클라이언트에서는 보여줘야한다. (index.html)
6. 정보 추가하기(마커띄우기, 정보창 infowindow 띄우기)
- 마커띄우기
function make_marker(matjip) {
let marker = new naver.maps.Marker({
position: new naver.maps.LatLng(matjip["mapy"], matjip["mapx"]),
map: map
});
markers.push(marker)
return marker
}
- 정보창 infowindow 띄우기
infowindow 가운데오게하기
map.setCenter(infowindow.position)
7. 고급기능사용 (카드보이게 스크롤 움직이기, 제목클릭 시 정보창 띄우기, og태그, favicon)
- 카드보이게 스크롤 움직이기
$("#matjip-box").animate({
scrollTop: $("#matjip-box").get(0).scrollTop + $(`#card-${i}`).position().top
}, 2000);
- 제목클릭 시 정보창 띄우기
a 태그를 클릭했을 때 새창이 뜨는게 아니라 javascript 함수를 실행하고 싶다면? → <a href="javascript:실행함수명()"> ...
function click2center(i) {
let marker = markers[i]
let infowindow = infowindows[i]
if (infowindow.getMap()) {
infowindow.close();
} else {
infowindow.open(map, marker);
map.setCenter(infowindow.position)
}
}
a 태크 수정내용
<a href="javascript:click2center(${i})" class="matjip-title">${matjip['title']}</a>
7. 즐겨찾기 기능
→ 이부분은 숙제 해설영상 보고 복습해보자!
온라인 강의에 관심이 있으신분들은 아래 링크로 수강하는경우 할인 가능합니다!
https://spartacodingclub.kr/?f_name=%EA%B0%95%ED%99%8D%EC%88%9C&f_uid=6044be3eea76fe086b066ce7
'내마음대로만들어보자 > HTML' 카테고리의 다른 글
웹 개발플러스 4주차(회원가입,로그인, 좋아요 기능 등) (0) | 2021.05.10 |
---|---|
앱 개발종합반 1주차 (자바스크립트) (0) | 2021.04.28 |
메가박스 사이트 만들기(HTML+CSS+Jquery) (0) | 2021.04.25 |
웹 개발플러스 2주차 나만의 단어장 만들기 (0) | 2021.04.25 |
웹개발 플러스 1주차 나홀로일기장 만들기 (0) | 2021.04.25 |