인프런 커뮤니티 질문&답변

김민석님의 프로필 이미지
김민석

작성한 질문수

[2024 개정판] 이것이 진짜 크롤링이다 - 실전편 (인공지능 수익화)

-

키워드입력시 오류

해결된 질문

작성

·

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"
  1. 네이버 지도가 바뀌어서 리뷰가 바뀌었습니다.
    위와 같이 새로 오픈한 가게로 해서 코드를 작성했는데 작동하지 않습니다. 어떻게 코드를 구성하면 좋을까요?

답변 2

0

스타트코딩님의 프로필 이미지
스타트코딩
지식공유자

1. 키워드로 강남역 맛집 / 이태원 술집으로는 엑셀파일로 저장이 잘 되는데 "행궁동 맛집"이라고 치면 아래와 같은 오류가 출력됩니다. 왜이러는 걸까요?

 

제가 테스트 해봤을 때는 강남역 맛집, 행궁동 맛집 모두 클릭하고 잘 동작하는데요

코드상의 문제는 없어 보입니다 ㅎㅎ

 

  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을 찾을 수 없을 때 발생할 수 있습니다. 별점이 있는 경우만 namestar를 찾도록 조건을 주셨기 때문입니다. 이 문제를 해결하기 위해서 namestar를 찾는 조건문 안에서만 printws.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)를 사용하여 해당 요소의 구조를 파악하고, 셀렉터를 직접 찾아보는 것입니다. 예를 들어, 리뷰 수를 나타내는 새 셀렉터를 찾고 이를 코드에 반영해야 할 것입니다.

추가적인 도움이 필요하시면 강의 ‘이것이 진짜 크롤링이다 - 실전편’의 커뮤니티 질문&답변 게시판에 질문을 올려 주시면 강사님께서 확인하시고 답변을 해주실 것입니다.

김민석님의 프로필 이미지
김민석

작성한 질문수

질문하기