인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

최지훈님의 프로필 이미지
최지훈

작성한 질문수

[2024 개정판] 이것이 진짜 크롤링이다 - 기본편

셀레니움_for 문 질문

해결된 질문

작성

·

1.1K

1

안녕하십니까
양질의 강의 잘 듣고 있습니다. 감사합니다.

네이버 쇼핑에 아이폰13을 검색하는 부분에 관하여
질문드리고 싶은 부분이 있습니다.

무한스크롤에 크롤링까지는 잘 되지만,

가장 상단의 결과 딱 하나만 가져와지고, 나머지 항목들은 크롤링이 되지 않습니다.

반복문에 문제가 있는 것으로 추정되는데 어디가 문제인지 찾는데 어려움이 있습니다.

긴 글 읽어주셔서 감사하고, 아래는 제가 강사님 따라한 코드입니다.

 

 

# 셀레니움에서 스크롤을 자동으로 내리고 크롤링하는 방법을 알아보자.
import imp
from lib2to3.pgen2 import driver
from tkinter import BROWSE
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

# 브라우저 자동으로 꺼짐 방지
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())
driver = webdriver.Chrome(service=service, options=chrome_options)

# 특정 웹페이지 주소로 이동
driver.implicitly_wait(5) # 웹페이지가 로딩 될때까지 5초는 기다려준다
driver.maximize_window() # 화면 최대화
driver.get('https://www.naver.com/') # 네이버 열기

# 쇼핑 배너 클릭
banner = driver.find_element(By.CSS_SELECTOR, '#NM_FAVORITE > div.group_nav > ul.list_nav.type_fix > li:nth-child(5) > a') # 네이버 쇼핑 배너의 selector
banner.click() # id라는 변수를 클릭하라는 명령어다
time.sleep(2) # 쇼핑 배너를 클릭한 뒤, 아직 페이지가 뜨지도 않았는데 바로 다음 명령어가 실행될 수도 있으니까, 2초 정도 여유를 준다.

# 쇼핑 페이지에서 검색 클릭
search = driver.find_element(By.CSS_SELECTOR, '#_verticalGnbModule > div > div._header_header_REoTl > div > div._gnb_header_shop_Xd6Hq > div > div._gnbSearch_search_area_3LAyd > form > fieldset > div > input') # 네이버 쇼핑 배너의 selector
search.click() # id라는 변수를 클릭하라는 명령어다

# 검색어 입력
search.send_keys('아이폰 13')
search.send_keys(Keys.ENTER) # 검색어를 입력하고, 엔터를 치라는 명령어

# 무한 스크롤: 동적 사이트에서 자동으로 스크롤을 가장 아래까지 내려주는 알고리즘
# 스크롤을 내리기 전 기본이 되는 높이
before_h = driver.execute_script('return window.scrollY')

while True:
    # 맨 아래로 스크롤을 내린다.
    driver.find_element(By.CSS_SELECTOR, 'body').send_keys(Keys.END) # 대부분의 웹페이지는 body 태그가 다 있다. 이걸 이용하고, END를 통해 맨 아래까지 스크롤 내림
    # 너무 빠르면 오류가 생기니까 스크롤 사이에 페이지 로딩 시간을 주자.
    time.sleep(1)
    # 스크롤 후 높이
    after_h = driver.execute_script('return window.scrollY')

    if after_h == before_h:
        break
    before_h = after_h

# 상품정보 div
items = driver.find_elements(By.CSS_SELECTOR, '#__next > div > div.style_container__1YjHN > div.style_inner__18zZX > div.style_content_wrap__1PzEo > div.style_content__2T20F > ul > div > div:nth-child(1) > li > div > div.basicList_info_area__17Xyo')
for item in items:
    name = item.find_element(By.CSS_SELECTOR, '#__next > div > div.style_container__1YjHN > div.style_inner__18zZX > div.style_content_wrap__1PzEo > div.style_content__2T20F > ul > div > div:nth-child(1) > li > div > div.basicList_info_area__17Xyo > div.basicList_title__3P9Q7').text
    price = item.find_element(By.CSS_SELECTOR, '#__next > div > div.style_container__1YjHN > div.style_inner__18zZX > div.style_content_wrap__1PzEo > div.style_content__2T20F > ul > div > div:nth-child(1) > li > div > div.basicList_info_area__17Xyo > div.basicList_price_area__1UXXR > strong > span > span.price_num__2WUXn').text
    link = item.find_element(By.CSS_SELECTOR, '#__next > div > div.style_container__1YjHN > div.style_inner__18zZX > div.style_content_wrap__1PzEo > div.style_content__2T20F > ul > div > div:nth-child(1) > li > div > div.basicList_info_area__17Xyo > div.basicList_title__3P9Q7 > a').get_attribute('href')
    print(name, price, link)

답변 1

0

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

오른쪽 클릭 후 copy -> copy selector 를 하면 한개 밖에 못가져 옵니다.

다시 한번 강의를 천천히 돌려보면서 제가 CSS 선택자를 만드는 방식을 학습해 소베요 ^^

최지훈님의 프로필 이미지
최지훈

작성한 질문수

질문하기