작업자의 크롬과 동일한 버전의 chromedriver 설치하여, 작업 파일과 동일한 폴더에 넣어주어야 합니다.
1) 크롬 버전 확인 2) chromedriver 설치
from selenium import webdriver
import requests
from bs4 import BeautifulSoup as bs
from selenium.webdriver import ActionChains as ac
import pandas as pd
import time
from selenium.webdriver.support.select import Select
# 새민 크롬드라이버
path = 'C:/selenium_server/chromedriver.exe'
driver = webdriver.Chrome(path)
# 주현 크롬드라이버
#driver = webdriver.Chrome('./chromedriver')
# 페이지 로딩 대기 5초
driver.implicitly_wait(5)
# 페이지 가져오기 & 파싱
driver.get('https://www.agoda.com/ko-kr/glad-live-gangnam_2/hotel/seoul-kr.html?finalPriceView=1&isShowMobileAppPrice=false&cid=1829971&numberOfBedrooms=&familyMode=false&adults=2&children=0&rooms=1&maxRooms=0&checkIn=2020-12-11&isCalendarCallout=false&childAges=&numberOfGuest=0&missingChildAges=false&travellerType=1&showReviewSubmissionEntry=false¤cyCode=KRW&isFreeOccSearch=false&tag=747e9723-83df-6f99-853a-8505c70753f7&los=1&searchrequestid=509f890e-e014-4df7-a231-a744ecd2194c')
html = driver.page_source
soup = bs(html, 'html.parser')
# 리뷰 영역까지 스크롤
scroll_point = driver.find_element_by_id('reviewFilterSection')
ac(driver).move_to_element(scroll_point).perform()
html = driver.page_source
soup = bs(html, 'html.parser')
button = driver.find_element_by_xpath('//*[@id="reviewFilterSection"]/div[3]/div[1]')
ac(driver).move_to_element(button).click().perform
time.sleep(2)
button = driver.find_element_by_xpath('//*[@id="reviewFilterSection"]/div[3]/div[1]')
ac(driver).move_to_element(button).click().perform
time.sleep(2)
button = driver.find_element_by_xpath('//*[@id="reviewFilterSection"]/div[1]/div[3]')
ac(driver).move_to_element(button).click().perform()
time.sleep(2)
#한국어클릭
button = driver.find_element_by_xpath('//*[@id="reviewFilterSection"]/div[1]/div[3]/div/ul/li[2]')
ac(driver).move_to_element(button).click().perform()
time.sleep(2)
driver.implicitly_wait(5)
# 다시 파싱
html = driver.page_source
soup = bs(html, 'html.parser')
#총 리뷰 개수 찾기 : for문을 몇 번 돌릴지 구하기위함 (버튼을 몇 번 눌러야 할지)
html = driver.page_source
soup = bs(html, 'html.parser')
review_sum0 = soup.select('.Review__FilterContainer__Dropbox > span') #이게 아니었네용
review_sum0 = review_sum0[0].text.split("(")[1][:-1]
#실제 이용후기 개수
review_sum = soup.select('span.Review__SummaryContainer--left.Review__SummaryContainer__Text')[0].text
review_sum = review_sum.split(" ")[3][:-1]
pages = int(review_sum)//20 + 1
# 데이터프레임으로 만들 딕셔너리 정의
reviews = {'score':[], 'text':[]}
#page 넘어가기
for k in range(1,pages+1):
html = driver.page_source
soup = bs(html, 'html.parser')
# 리뷰 영역까지 스크롤
scroll_point = driver.find_element_by_id('review-0')
ac(driver).move_to_element(scroll_point).perform()
# 다시 파싱
html = driver.page_source
soup = bs(html, 'html.parser')
for k in range(0,9):
date_ = soup.select(f'#review-{k} > div.Review-comment-right > div.Review-comment-bubble > div.Review-statusBar > div > div > span')
year = date_[0].text.split(" ")[1][:-1]
if int(year) >= 2018:
score = soup.select(f'#review-{k} > div.Review-comment-left > div > div.Review-comment-leftHeader > div.Review-comment-leftScore')
text = soup.select(f'#review-{k} > div.Review-comment-right > div.Review-comment-bubble > div.Review-comment-body > p.Review-comment-bodyText')
reviews['score'].append(score[0].text)
reviews['text'].append(text[0].text)
else:
break
#버튼누르기
button = driver.find_element_by_xpath('//*[@id="reviewSection"]/div[4]/div/span[3]')
ac(driver).move_to_element(button).click().perform()
time.sleep(2)
#호텔명
hotel = soup.select('.HeaderCerebrum__Name')
hotel
[<h1 class="HeaderCerebrum__Name" data-selenium="hotel-header-name">글래드라이브 호텔 (Glad Live Gangnam)</h1>]
#호텔명
reviews['title'] = hotel[0].text
reviews
{'score': ['8.0', '8.8', '10.0', '6.4', '9.2', '10.0', '6.8', '9.6', '9.2', '8.4', '10.0', '10.0', '9.6', '8.0', '9.2', '9.6', '8.0', '8.4', '10.0', '8.4', '10.0', '9.2', '4.4', '8.4', '8.8', '8.0', '7.6', '8.8', '8.4', '9.2', '9.2', '8.8', '9.6', '10.0', '9.2', '8.8', '8.8', '8.4', '7.6', '8.4', '9.6', '9.6', '9.2', '8.0', '8.8', '8.0'], 'text': ['ㅇ', '글래드 계열 호텔 침구은 언제나 편안하고, 룸 청결 상태는 항상 좋습니다~', '오랜전부터 출장 때문에 자주 투숙하고 있습니다. 침대도 편안하고 모든게 좋은데 가격은 동일함에도 불구하고 점점 방문할수록 어매니티가 하나씩 사라져서 방문할 때마다 당황스럽네요^^', '지하철 역이랑 가까워서 좋아요', '넓은 침대와 긴 쇼파 2개로 5명까지 우리는 편하게 잤다.', '방이 깔끔하고 분위기도 좋고 주변에 맛집도 많아서 좋았습니다. 특히 블루투스스피커도 있어서 더욱 호캉스기분 났습니다~', '역에서 가깝고 좋아요', '위치도 좋고 숙소 상태도 깨끗해서 또 오고 싶네요\n고층 요청했더니 19층 주셨어요 감동~\n다음에는 파티룸을 이용할까해요 ', '강남에서 이 가격에 \n작은 파티할 만한 크기와 무드 \n분리된 거실을 가진 호텔은 여기뿐임.\n부대시설은 이용할 만한 것이 없지만\n주변 맛집 많고, 배달 안 되는 음식이 없다.', '기대한것보단 별로였음 마포가 더 좋음!', '위치도 좋고\n룸서비스도 만족\n룸컨디션도 아주 좋음\n\n이번이 재방문이고\n재재방문의사도 있음', '강남 주요 클럽이 5-10분 거리에 있고\n룸 인테리어도 만족\n배스가운이 매우 좋음\n하만카돈 스피커로 음악 듣고 힐링하기 좋음', '위치가 좀 길가다가 바로 있어서 차도 막히고 좀 불편했는데, 그거 빼고는 모든 것이 좋았습니다! 또 가고싶은 곳이에요~ ', '딱 가격대비 깔끔하고 글래드다운 디자인', '편했습니다 ', '일단 넓고 깨끗하고 깔끔해요\n고층 뷰도 앞에 시야가 뚫려서 좋네요', '침대가 푹신해서 편하게 잘 잤네요\n욕조가 있어서 좋았어요 생각보다 욕조가 컸어요\n위치는 지하철 역 바로 근처라 좋았지만 도로쪽이라서 소음이 조금 있었고 욕실에 머리카락이 조금 있었습니다 \n조식은 가격대비 생각보다 맛있어요 \n', '자차 이용시 기계식 주차기 입출차용 발렛비 추가됨.\n서울에 있는 글래드 호텔 계열만 다 발렛비 추가로 받는 듯.\n객실 깨끗\n조식 부페는 서울에 있는 글래드 계열 중에서 가장 안 좋은 듯함.\n음식이 8가지 정도임.\n조식부페는 비추', '너무좋아요! ', '서울에서의 시험을 위해 묵었던 호텔이였던만큼 밤에 시끄럽지는 않을까 라는 우려가 있었습니다만 우려와는 달리 너무 조용하고 좋았습니다 방도 깔끔하고 직원분들의대응도 좋았습니다 덕분에 컨디션조절도 잘되어 시험도 잘봤습니다:) 감사합니다~', '저렴하게 잘 이용하다 갑니다', '트윈룸예약! 룸컨디션좋고 침구좋고 디자인좋고 특히 샤워가운 재질이 너무마음에듬! 밤에 밖에 길거리나 호텔 내에 소음? 다른방 사람소리? 좀 시끄럽다 생각했고 잠자는데는 문제없을정도였음 체크아웃시간맞춰 체크아웃했는데 주차타워점검중이라고 20분정도 기다림 레스토랑 런치예약땜에 시간맞춰나왔는데 생각지도못한 딜레이에.. 레스토랑에 양해구하고 예약변경함 굳이 체크아웃시간에 점검했어야하는지의문 호텔투숙객인데 일찍가서 주차해놓는것도 추가요금내야되서 그점이 좀 별로였음 나머진매우만족! ', '룸 컨디션은 좋았지만, 추워서 온도를 올리는데 전체적으로 방이 따뜻해지는 느낌은 없고 춥게 잤네요 천장에 있는 난방시스템의 필터가 오래된건지 아침에 목만 아프고, 여전히 방은 추웠습니다. \n체크인날 조식떄문에 모닝콜 부탁했는데 전화를 안해 주시더라고요\n느즈막히 일어나서 조식을 먹었는데 조식또한 돈내고 먹기 아까운 정도 였어요...\n일단 돈이 아깝다는 생각이 많이 들어서 조식은 추천하지 않겟습니다. ', '가격대비 룸 컨디션 아주좋습니다\n공간도 넉넉하니 잘 쉬다왔습니다\n다만 밤에 위쪽에 라운지에서 나는 소리인지 음악소리가 쿵쿵대는데 꽤 거슬리더라구요 12시쯤되니 꺼지긴 했지만 상당히 크게 들렸어요 베이스\n쿵쿵대는 소리요\n그리고 발렛 직원 아주 불친절하네요\n체크아웃할때 기분 팍 상해서 나왔네요 ..쩝', '어메니티 (칫솔 치약은 없음) 나머지는 괜찮음, 나이트가운이 너무 좋아서 가지구오고 싶음\n침구류 좋음\n조명 좋음! 주왕색으로 적절한 밝기라서 좋음\n기타 하만 블루투스 스피커가 있음 노래틀어놓고있기 너무 좋음!\n 수압, 핫워터 다 잘 나오고 좋음\n 바로옆 편의점이 있어서 편함.\n', '일단 위치는 별로예요,,ㅠ 강남까지 걸어가기 좀 애매하긴 한데 호텔 근처에는 편의점 등등 있을거 다 있어서 좋았어요~ 위생은,, 이불에 까만 먼지?같은게 묻어있어서 별두개 뺐어요. 지난번에 묵었을 때 깔끔해서 다시 찾은거였는데😢 그리고 트리플룸은 통창이 아니고 옆건물이랑 붙어 있어서 뷰라는게 전혀 없었어요 참고하세용', '모든 직원분들 서비스는 최고라고 할수 있습니다 물론 호텔상태도 깨끗하고 분위기 좋아요 위치도 너무 좋습니다 그래서 전 한국에 올때 마다 이 호텔에서만 지냅니다\n그리고 Harry 라는 직원 정말 친절 합니다\n개인적인 어떤일도 잘 도와주시고 감동 이었어요\n그리고 침대 매트리스 너무 편해요 잠 정말 편하게 잘수있어요 \n', '가격대비 큰 룸때문에 좋았습니다.', '방에서 냄새가 나서 프론트에 전화를 했더니 바로 바꿔주셨습니다. 하지만 바꿔줬던 방이 복도 제일 끝방이라서 그랬는지, 아니면 에어컨이 고장났었는지 모르지만, 저녁 내내 에어컨을 틀어놓아도 방 온도가 1도조차 떨어지지 않아 너무 더웠습니다. ㅜㅜ ', '1대만 주차되지만 주차도 발렛이어서 편하고, 전체 금연객실이라 냄새없고 조용해요.\n침구도 편안하고 쉬기에 좋은 호텔입니다.\n다만 조식은 특징도 없고 절대적으로 비추예요', '체크인-아웃시간이 조금 타이트하긴하지만 가격대비 위치와 룸상태 모두 만족해요! 최근 바뀐 어메니티도 맘에 들어요 !', '룸컨디션, 인테리어가 정말 기대이상으로 좋았고 침구도 편안했다.\n아쉬운 점이라면 휴대폰충전기대여는 안되서 챙겨가길 추천', '블루투스 스피커가 있어서 하루종일 음악 틀어놓고 정말 편하게 있었어요. 침대도 편하고 정말 만족스러운 스테이였습니다.', '깔끔하고 전 너무 좋았어요 소음은 18층이여서 그런지 잠을 못 잘정도는 아니였어요. ', '글래드 하우스 이용했습니다 다른 호텔대비 가격은 저렴하나 모든 면에서 만족하는 호텔이었습니다. 청결하고 공간도 넓고 스피커도 재밌었구요 티비도 두대! 다만 어메니티가 별로 없어서 아쉬웠지만 그래도 아주 만족스러운 호텔이었어요', '재우기위해 여러 숙소를 찾아봤는데,\n일단 베드 사이즈가 큰편이라서, 5세이하 아이는 무료니까\n가성비 훌륭했던 것 같습니다\n또 이용하고싶네요!', '시간이 애매해서 하루 숙소에서 묵었네요~\n더채플서 식을 올렸는데 근처 숙소 찾다가 발견\n위치 정말 좋아요~ 베드도 크고! 무난합니다', '대체적으로 만족', '방은 전체적으로 깨끗하고 관리가 잘 되어 있었음. 화장실과 욕실이 분리되어 있어 사용하기 편리했고 드라이기, 수건, 애너미티들이 잘 구비되어 있었음. 치약과 칫솔은 구매해서 사용해야함. \n침구 상태도 깨끗했고 포근해서 좋았으나 방음이 좋지 못햇음. \n지하에 클럽 운영이 종료되어 조용할 것이라 예상했으나 도로에 차량 다니는 소음이 들릴 정도로 방음에 취약함. 클럽 소음이 커서 시끄러웠던게 아니라 애초에 방음에 취약하게 만들어진 건물 같음. 복도 지나갈때는 방에서 뭐하는 지 들릴 정도... ', '3인실에는 베드 가운데 테이블이 있어 친구들과 놀라 갔을 때 놀기 좋음. 방은 깨끗하고 침구는 편안했지만 방음이 잘 안됨.\n방안에서 옆방 소리는 들리지 않지만 도로 노면 소음이 다 들릴 정도.. 클럽 운영이 종료되어 그 소음은 없음. ', '로비가 4층에있어서 조금 불편했어요 전체적인 분위기는 모던하지만 정말 군더더기없는 느낌이랄까?\n호텔로서의 기본에 충실했지만 트렌디한점도 놓치지않고 가격대비 매우 만족했습니다 . ', '5성급 호텔에 못지않은 방 크기, 가구 와 청결, 적당한 가격..\n아주 만족하며 서울 방문시 다시 찿을 예정입니다.', '업무차 서울방문시 거래처근처라 작년에 처음 묶고 올해 두번째로 체류했읍니다.\n가격도 적당하고 방크기, 구조 가구등이 매우 편리했읍니다.\n도리어 5성급의 비싼호텔보다 방이 좀 큰듯하고 의자도 편합니다.\n로비가 4층이라 방문객이 좀 당황할수 있으나 투숙객입장은 위치를 포함 깨끗하고 좋은 호텔이라고 봅니다.', '깔끔한 부티크 호텔입니다. 평일에 가서 그런지 조용하고 괜찮았어요. ', '대체적으로 편안하고 깨끗하면서 교통이 좋았어요\n하지만 주차가 타워형이라 꺼낼때 까지 기다려야 하는 점이 별로네요\n전반적으로 좋습니다!', '지하에 클럽이 있어서 목금토는 음악소리가 좀 울려요. 제가 묵은 객실은 중간쯤이었는데 저층은 방해가 될 정도라고 하더라구요. \n고층 객실로 체크인 하는 방법을 미리 문의했었는데 딱히 방법은 없다는 답변을 들었습니다.'], 'title': '글래드라이브 호텔 (Glad Live Gangnam)'}
df = pd.DataFrame(data = reviews)
df["title"] = df["title"].map(lambda x: x.split("(")[0])
df["title"] = df["title"].map(lambda x:x.strip())
df = df.drop_duplicates()
df.head()
score | text | title | length | |
---|---|---|---|---|
0 | 8.0 | ㅇ | 글래드라이브 호텔 | 1 |
1 | 8.8 | 글래드 계열 호텔 침구은 언제나 편안하고, 룸 청결 상태는 항상 좋습니다~ | 글래드라이브 호텔 | 41 |
2 | 10.0 | 오랜전부터 출장 때문에 자주 투숙하고 있습니다. 침대도 편안하고 모든게 좋은데 가격... | 글래드라이브 호텔 | 99 |
3 | 6.4 | 지하철 역이랑 가까워서 좋아요 | 글래드라이브 호텔 | 16 |
4 | 9.2 | 넓은 침대와 긴 쇼파 2개로 5명까지 우리는 편하게 잤다. | 글래드라이브 호텔 | 32 |
df.isnull().sum()
score 0 text 0 title 0 dtype: int64
df["length"] = df["text"].map(lambda x: len(x))
df.to_csv("글래드라이브호텔.csv")