행님덜~~네이버 플레이스리뷰 크롤링 좀 도와주세요!!!

조회수 1093회

행님덜 네이버 플레이스 리뷰 크롤링을 할려고 하는데 리뷰 중에 사진만 있고 텍스트는 없는 리뷰도 있지 않습니까?

제가 짠 코드는 매장명, 아이디, 리뷰를 끌어 오는데 사진만 있는 경우에는 누락시키고 바로 다음 텍스트를 가져옵니다 ㅜㅜㅜ 이런 문제가 발생하면 예를 들어서 다섯번째 매장명, 다섯번째 아이디, 여섯번째 리뷰 이런 식으로 출력이 됩니다 사진만 있는 리뷰인 경우에 "사진만 있는 리뷰입니다"를 출력할 수 있는 방법이 있을까요?

from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By import time from bs4 import BeautifulSoup as bs from openpyxl import Workbook import re

Create a new Excel workbook

workbook = Workbook()

sheet = workbook.active

청년다방 URL

urls = [ "https://m.place.naver.com/restaurant/1699730089/review/visitor?entry=ple", # Rest of your URLs... ]

크롬드라이버 경로

driver_path = r'C:\Users\USER\PycharmProjects\pythonProject2\venv\Lib\site-packages\chromedriver_autoinstaller\114\chromedriver.exe'

크롬 드라이버 설정

service = Service(driver_path) driver = webdriver.Chrome(service=service) driver.implicitly_wait(10) print("Chrome 드라이버 경로:", driver_path) countOfreview = [] countOfid = [] row = 2 # Starting row index

for url in urls: # 셀레니움으로 크롬 브라우저 열기 driver.get(url) driver.implicitly_wait(10)

# 스크롤 내리기
scroll_pause_time = 1  # 스크롤 동작 후 대기 시간 (초)
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    try:
        # "더보기" 버튼 클릭
        more_button = driver.find_element(By.XPATH, '//*[@id="app-root"]/div/div/div/div[7]/div[2]/div[3]/div[2]/a')
        more_button.click()

        # 데이터 로딩을 위해 충분한 시간을 주고, 새로운 높이 계산
        time.sleep(1)  # 필요한 시간을 조절할 수 있습니다.
        new_height = driver.execute_script("return document.body.scrollHeight")

        # 새로운 높이와 이전 높이를 비교하여 스크롤이 더 이상 필요하지 않으면 종료
        if new_height == last_height:
            break

        # 스크롤 이동 후의 높이를 이전 높이로 업데이트
        last_height = new_height
    except:
        break

    # 스크롤 후 데이터가 모두 로드되었는지 확인하는 시간 대기
    time.sleep(2)  # 웹 페이지의 로딩 속도와 데이터 양에 따라 조절합니다.

# 스크롤이 끝난 후에 출력


# 매장명 가져오기
store_name_element = driver.find_element(By.CSS_SELECTOR, '.bh9OH')
store_name = store_name_element.text.strip()
# 리뷰 가져오기
id_elements = driver.find_elements(By.CSS_SELECTOR, '.VYGLG')
caption_elements = driver.find_elements(By.CSS_SELECTOR, '.zPfVt')

for id_element, caption_element in zip(id_elements, caption_elements):
    id_text = id_element.text.strip()
    caption_text = caption_element.text.strip()
    print(f"{id_text}          {caption_text}")
    countOfreview.append(caption_text)
    countOfid.append(id_text)



    # Remove illegal characters from the caption_text
# Remove illegal characters from the caption_text

# 엑셀에 저장
#sheet.cell(row=row, column=1, value=store_name)
#sheet.cell(row=row, column=2, value=clean_text)

row += 1

print("-----------------------------------")

Save the workbook

workbook.save("rsdadasdasdqsada42542sdaㄴㅁㅇㅁㄴㅇㅁㅇiews.xlsx")

print(f"아이디 개수 : {len(countOfid)}")
print(f"리뷰 개수 : {len(countOfreview)}")

웹드라이버 종료

driver.quit()

1 답변

  • 1. 셀레니움이나 파이썬 전반적으로 잘 모르지만 zip()을 무턱대고 진행하고 계신 게 문제 같습니다. id_elements의 갯수와 caption_elements의 갯수가 다를 수 있다면, 그걸 zip() 하시면 안될 거 같은데 말이죠.

    2. HTML 마크업 자체가 id 요소 안에 caption 요소가 (선택적으로) 들어 있는 구조라면, 혹시 이런 식으로 되나요?

    for id_element in id_elements:
        caption_element = driver.find_elements(By.CSS_SELECTOR, '.VYGLG .zPfVt') # 아마 될거 같은데 실제로는 어떤지 모르겠네요.
        if (caption_element is None) : # "caption 요소가 없다"는 부분 표현인데 대충 걸러들어 주세요.
            print('캡션이 없어서 통과...')
            pass
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)