전에 find_elements의 리스트 결과에서 텍스트를 뽑아내는 방법을 여쭤봤습니다.
(1) 네이버 맛집 검색 결과에서 len을 사용해 영업중인지 여부를 파악하는것 + (2) 영업중이라면 "영업중"이라는 결과가 text로 나오게 하는 것
# 데이터 저장 후 마무리
import imp
from lib2to3.pgen2 import driver
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import pyautogui
import openpyxl
keyword = pyautogui.prompt("검색어를 입력하세요")
wb = openpyxl.Workbook()
ws = wb.create_sheet(keyword)
ws.append(["순위", "이름", "별점", "방문자리뷰", "블로그리뷰"])
# 크롬 드라이버 자동 업데이트
from webdriver_manager.chrome import ChromeDriverManager
# 브라우저 자동으로 꺼짐 방지
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
# 불필요한 에러 메시지 삭제
chrome_options.add_experimental_option("excludeSwitches", ["enable-logging"])
# 셀레니움으로 웹브라우저 자동으로 띄우기
# ChromeDriverManager를 통해서 ChromeDriver를 설치하고, Service라는 객체를 만든 뒤, service라는 변수에 저장한다
service = Service(executable_path=ChromeDriverManager().install())
browser = webdriver.Chrome(service=service, options=chrome_options)
# 특정 웹페이지 주소로 이동
browser.implicitly_wait(5) # 웹페이지가 로딩 될때까지 5초는 기다려준다
browser.maximize_window() # 화면 최대화
browser.get('https://map.naver.com/v5/?c=14141023.2182021,4522932.8702864,15,0,0,0,dh')
# 검색 배너 클릭
search = browser.find_element(By.CSS_SELECTOR, "input.input_search")
search.click()
time.sleep(1)
# 검색어 입력
search.send_keys(keyword)
search.send_keys(Keys.ENTER) # 검색어를 입력하고, 엔터를 치라는 명령어
time.sleep(2)
# iframe 안으로 들어가기
browser.switch_to.frame("searchIframe") # searchIframe는 iframe의 id다.
# 들어가는 것과 반대로, iframe 밖으로 나와서 원래 사이트로 돌아가는것
# browser.switch_to_default_content()
# iframe 안쪽 클릭하기
browser.find_element(By.CSS_SELECTOR, "#_pcmap_list_scroll_container").click()
# 로딩된 데이터 개수 확인
lis = browser.find_elements(By.CSS_SELECTOR, "li._1EKsQ")
before_len = len(lis) # lis를 통해 각 가게를 나타내는 li를 가져오고, len을 통해 몇 개가 있는지를 확인한다.
while True:
# 맨 아래로 스크롤을 내리자.
browser.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END) # 아무 태그나 선택하기 위해서 body를 선택한다.
# 스크롤 사이에 페이지 로딩 시간을 기다려주자
time.sleep(1.5)
# 스크롤 후 로딩된 데이터 개수 확인
lis = browser.find_elements(By.CSS_SELECTOR, "li._1EKsQ")
after_len = len(lis)
# print("스크롤 전", before_len, "스크롤 후", after_len)를 추가해서, 실제로 스크롤이 잘 되는지 결과를 확인할 수 있다(word 참조)
# 로딩된 데이터 개수가 같아지면(= 한 페이지에서 더이상 스크롤을 내려도 새로운 정보가 없다면) 반복 멈춰라
if before_len == after_len:
break
before_len = after_len # 만약 before_len == after_len가 True가 아니라면, before_len을 after_len으로 만들어주라
# for문 시작하기 전에, 데이터 기다리는 시간을 0으로 만들어주자(데이터가 없는건 그냥 빠르게 넘어간다)
browser.implicitly_wait(0)
rank = 1
for li in lis: # lis는 가게 정보를 담고 있으니까 여기에 for문을 써서 가게정보를 가져오자
# 광고상품 아닌 것만 -> len을 넣어서 결과가 0이라면 광고 CSS에 아무 결과가 없다는 뜻이다.
# 그 뒤, 아래 기존 명령어를 전부 drag하고 tab을 눌러주자.
if len(li.find_elements(By.CSS_SELECTOR, "svg._2ulu3")) == 0:
# 별점이 있는 가게만 가져오자
# 별점부분 정보를 가져왔을 때, 해당 리스트의 길이가 0보다 크다면, 즉, 무언가 별점에 관한 정보가 있다면 명령문을 진행한다.
if len(li.find_elements(By.CSS_SELECTOR, "span._2FqTn._1mRAM > em")) > 0: # word 참조
# 가게명
name = li.find_element(By.CSS_SELECTOR, "span.place_bluelink.OXiLu").text
# 별점
star = li.find_element(By.CSS_SELECTOR, "span._2FqTn._1mRAM > em").text
# 영업 시간이 있다면?
if len(li.find_elements(By.CSS_SELECTOR, "span._2FqTn._4DbfT")) > 0: # 영업중이든 종료든 무언가 정보가 있다면 다음을 실행하라는 뜻
# 방문자 리뷰수
try:
visit_review = li.find_element(By.CSS_SELECTOR, "span._2FqTn:nth-child(3)").text
except:
visit_review = "0" # try의 결과가 text니까, try의 명령어가 True가 아닌 결과값도 ""를 통해 text 형태로 만들어주자.
# 블로그 리뷰수
try:
blog_review = li.find_element(By.CSS_SELECTOR, "span._2FqTn:nth-child(4)").text
except:
blog_review = "0"
# 영업 시간이 없다면: 제일 앞에 span 태그가 하나 사라지니까, nth-child도 하나씩 숫자를 줄이자
else:
# 방문자 리뷰수
try:
visit_review = li.find_element(By.CSS_SELECTOR, "span._2FqTn:nth-child(2)").text
except:
visit_review = "0"
# 블로그 리뷰수
try:
blog_review = li.find_element(By.CSS_SELECTOR, "span._2FqTn:nth-child(3)").text
except:
blog_review = "0"
# print 전 데이터 전처리
visit_review = visit_review.replace("방문자리뷰 ", "").replace(",", "")
blog_review = blog_review.replace("블로그리뷰 ", "").replace(",", "")
print(rank, name, star, visit_review, blog_review)
ws.append([rank, name, float(star), int(visit_review), int(blog_review)])
rank = rank + 1 # rank를 저장한 뒤, for문 마지막에 1개 더 높여주자.
wb.save(f"{keyword}.xlsx")