해결된 질문
작성
·
335
·
수정됨
1
안녕하세요 선생님 2가지의 질문이 있습니다.
아래와 같이 코드를 구성했습니다.
1. 키워드로 강남역 맛집 / 이태원 술집으로는 엑셀파일로 저장이 잘 되는데 "행궁동 맛집"이라고 치면 아래와 같은 오류가 출력됩니다. 왜이러는 걸까요?
제 생각엔 "이태원 술집" , "강남역 맛집"에서는 iframe 안쪽을 한번 클릭 하는 것이 실행이 되는 것 같은데 "행궁동 맛집", "용산역 맛집"에서는 검색어 입력 후 iframe 클릭 하지 않고 바로 스크롤이 되는 것 같습니다.
C:\CRAWLLING>C:/Users/libra_erv8ij1/AppData/Local/Programs/Python/Python312/python.exe c:/CRAWLLING/CRAWLING심화/ch7.네이버지도크롤링/06.데이터저장.py
c:\CRAWLLING\CRAWLING심화\ch7.네이버지도크롤링\06.데이터저장.py:85: SyntaxWarning: invalid escape sequence '\c'
wb.save(f"CRAWLING심화\ch7.네이버지도크롤링\\{keyword}.xlsx")
Traceback (most recent call last):
File "c:\CRAWLLING\CRAWLING심화\ch7.네이버지도크롤링\06.데이터저장.py", line 81, in <module>
print(rank, name, star)
^^^^
NameError: name 'name' is not defined
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
from webdriver_manager.chrome import ChromeDriverManager
import pyautogui
import openpyxl
keyword = pyautogui.prompt("검색어를 입력하세요")
wb = openpyxl.Workbook()
ws = wb.create_sheet(keyword)
ws.append(["순위", "이름", "별점"])
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
chrome_options.add_experimental_option('excludeSwitches', ["enable-logging"])
service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.implicitly_wait(10)
driver.maximize_window()
driver.get("https://map.naver.com/v5/")
search = driver.find_element(By.CSS_SELECTOR, "input.input_search")
search.click()
time.sleep(1)
search.send_keys(keyword)
time.sleep(1)
search.send_keys(Keys.ENTER)
time.sleep(2)
# iframe 안으로 들어가기
driver.switch_to.frame("searchIframe")
# driver.switch_to_default_content() iframe 밖으로 나오기
# iframe 안쪽을 한번 클릭
driver.find_element(By.CSS_SELECTOR, "#_pcmap_list_scroll_container").click()
# 로딩된 데이터 개수 확인
lis = driver.find_elements(By.CSS_SELECTOR, "li.UEzoS")
before_len = len(lis)
while True:
# 맨 아래로 스크롤 내린다
driver.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END) # 아무 태그나 선택하기 위해 body를 선택하는 것
# 스크롤 사이 페이지 로딩 시간
time.sleep(1.5)
# 스크롤 후 로딩된 데이터 개수 확인
lis = driver.find_elements(By.CSS_SELECTOR, "li.UEzoS")
after_len = len(lis)
# 로딩된 데이터 개수가 같다면 반복 멈춤
if before_len == after_len:
break
before_len = after_len
# 데이터 기다리는 시간을 0으로 만들어줌 (데이터가 없어도 빠르게 넘어감)
driver.implicitly_wait(0)
rank = 1
for li in lis:
# 광고상품 아닌것만
if len(li.find_elements(By.CSS_SELECTOR, "svg.dPXjn")) == 0:
# 별점이 있는 것만 크롤링
if len(li.find_elements(By.CSS_SELECTOR, "span.h69bs.orXYY")) > 0:
# 가게명
name = li.find_element( By.CSS_SELECTOR, "span.TYaxT").text
# 별점
star = li.find_element(By.CSS_SELECTOR, ".h69bs.orXYY").text.split('\n')[1]
print(rank, name, star)
ws.append([rank, name, float(star)])
rank = rank + 1
wb.save(f"CRAWLING심화\ch7.네이버지도크롤링\\{keyword}.xlsx")
# 새롭게 오픈한 가게이면
if len(li.find_elements(By.CSS_SELECTOR, "span.h69bs.DjPAB")) > 0:
try:
# 방문자 리뷰수
visit_review = li.find_element(By.CSS_SELECTOR,"span.h69bs:nth-child(3)").text
except:
visit_review = "0"
# 새로 오픈한 가게가 아니면
else:
try:
visit_review = li.find_element(By.CSS_SELECTOR,"span.h69bs:nth-child(2)").text
except:
visit_review = "0"
네이버 지도가 바뀌어서 리뷰가 바뀌었습니다.
위와 같이 새로 오픈한 가게로 해서 코드를 작성했는데 작동하지 않습니다. 어떻게 코드를 구성하면 좋을까요?
답변 2
0
1. 키워드로 강남역 맛집 / 이태원 술집으로는 엑셀파일로 저장이 잘 되는데 "행궁동 맛집"이라고 치면 아래와 같은 오류가 출력됩니다. 왜이러는 걸까요?
제가 테스트 해봤을 때는 강남역 맛집, 행궁동 맛집 모두 클릭하고 잘 동작하는데요
코드상의 문제는 없어 보입니다 ㅎㅎ
리뷰가져오기
nth-child를 하나씩 더 증가 시키면 정상적으로 잘 가져옵니다!
# 새롭게 오픈한 가게이면
if len(li.find_elements(By.CSS_SELECTOR, "span.h69bs.DjPAB")) > 0:
try:
# 방문자 리뷰수
visit_review = li.find_element(By.CSS_SELECTOR,"span.h69bs:nth-child(4)").text
except:
visit_review = "0"
# 새로 오픈한 가게가 아니면
else:
try:
visit_review = li.find_element(By.CSS_SELECTOR,"span.h69bs:nth-child(3)").text
except:
visit_review = "0"
0
안녕하세요, 인프런 AI 인턴입니다.
먼저 “행궁동 맛집” 검색 시 발생하는 오류에 대해 설명드리겠습니다. 제공해주신 코드를 보았을 때, 발생한 오류인 NameError: name 'name' is not defined
는 변수 name
이 정의되지 않았거나 접근 가능 범위에 없을 때 발생합니다. 이 문제는 일부 맛집에 별점이 없어서 name
을 찾을 수 없을 때 발생할 수 있습니다. 별점이 있는 경우만 name
과 star
를 찾도록 조건을 주셨기 때문입니다. 이 문제를 해결하기 위해서 name
과 star
를 찾는 조건문 안에서만 print
와 ws.append
를 실행하도록 코드를 조정해야 합니다.
if len(li.find_elements(By.CSS_SELECTOR, "span.h69bs.orXYY")) > 0:
# 별점이 있을 경우에만 아래 코드를 실행
name = li.find_element(By.CSS_SELECTOR, "span.TYaxT").text
star = li.find_element(By.CSS_SELECTOR, ".h69bs.orXYY").text.split('\n')[1]
print(rank, name, star)
ws.append([rank, name, float(star)])
else:
# 별점이 없는 경우 다음 항목으로 건너뛰기
continue
rank = rank + 1
또한 파일 경로를 지정할 때 발생한 SyntaxWarning: invalid escape sequence '\c'
경고는 문자열에 역슬래시()를 사용할 때 발생합니다. Python은 역슬래시를 이스케이프 문자로 인식하기 때문에, 경로를 표시할 때는 이중 역슬래시(\)를 사용하거나 raw string 표기법인 앞에 r
을 붙여야 합니다. 예를 들어, f"CRAWLING심화\\ch7.네이버지도크롤링\\{keyword}.xlsx"
또는 rf"CRAWLING심화\ch7.네이버지도크롤링\{keyword}.xlsx"
와 같이 쓸 수 있습니다.
두 번째 질문인 네이버 지도 리뷰 관련해서는, 웹 사이트 구조가 바뀌면 해당 웹사이트의 현재 구조를 분석하여 셀렉터를 새롭게 설정해주어야 합니다. 위 코드에서는 span.h69bs.DjPAB
, span.h69bs:nth-child(3)
, span.h69bs:nth-child(2)
와 같이 셀렉터를 사용하고 있습니다만, 네이버 지도의 현재 구조에 맞게 셀렉터를 업데이트해야 할 수 있습니다. 이 때 주로 사용되는 도구는 개발자 도구(F12)를 사용하여 해당 요소의 구조를 파악하고, 셀렉터를 직접 찾아보는 것입니다. 예를 들어, 리뷰 수를 나타내는 새 셀렉터를 찾고 이를 코드에 반영해야 할 것입니다.
추가적인 도움이 필요하시면 강의 ‘이것이 진짜 크롤링이다 - 실전편’의 커뮤니티 질문&답변 게시판에 질문을 올려 주시면 강사님께서 확인하시고 답변을 해주실 것입니다.