셀레니움(selenium)

셀레니움으로 화면 스크롤 내려보자 (with 파이썬)

유니네 라이브러리 2024. 5. 4. 20:35

웹 자동화를 할 때 특정 웹 페이지에서 화면을 스크롤해야 하는 경우가 많다.

예를 들어,

  • 인피니티 스크롤(무한 스크롤) 페이지에서 더 많은 데이터를 로드할 때
  • 특정 지점까지 자동으로 이동해야 할 때

이때, Selenium(셀레니움) 을 사용하면 JavaScript의 window.scrollTo() 메서드를 활용해 쉽게 스크롤을 조작할 수 있다.

 

1. Selenium에서 화면 스크롤 내리기

 

셀레니움에서는 JavaScript 코드execute_script() 메서드를 이용하여 실행할 수 있다.

스크롤을 내릴 때는 window.scrollTo(from, to)를 사용하여 현재 위치에서 일정 거리만큼 이동하는 방식으로 구현할 수 있다.

 

✔ 기본적인 스크롤 코드 예시

def webScroll(i_present_location):
	  print("#####Start Scroll#####")
    time.sleep(1)
    #스크롤 시작지점 초기화
    from_scroll_height = 0
    #스크롤 종료지점 초기화
    to_scroll_height = 500
    last_height = driver.execute_script("return document.body.scrollHeight")    
    
    while True:
        #scroll 진행
        driver.execute_script("window.scrollTo("+ str(from_scroll_height) + "," + str(to_scroll_height) + ")")
        time.sleep(1)
        #현재 스크롤 위치
        present_location = driver.execute_script("return window.pageYOffset")
        #페이지 하단에 위치하면 종료
        if last_height == present_location:
            #하단 메뉴 보이고 나가기
            driver.execute_script("window.scrollTo("+ str(to_scroll_height) + "," + str(from_scroll_height) + ")")
            break
        #현 위치값이 인수로 넘어온 값보다 커지면 종료
        elif present_location > i_present_location:
            driver.execute_script("window.scrollTo("+ str(to_scroll_height) + "," + str(from_scroll_height) + ")")
            break
        else:
            #이동여부 판단 기준이 되는 이전 위치 값 수정
            last_height = driver.execute_script("return window.pageYOffset")
            #하단 위치 +500 씩 이동
            from_scroll_height = to_scroll_height + 1
            to_scroll_height = to_scroll_height + 500
print("#####End Scroll#####")
#스크롤 함수 호출 : 함수에 넘기는 인수는 무한스크롤에 대처하기 위해 현 스크롤 위치가 인수값을 넘기면 종료시키기 위해 전달
webScroll(30000)

 

2. 네이버 쇼핑 페이지에서 스크롤하기 (실전 예제)

 

아래는 네이버 쇼핑 메인 페이지에서 자동으로 스크롤을 내리는 코드이다.

특징:

  • 시크릿 모드로 크롬 브라우저 실행
  • iPhone 12 Pro 환경(모바일 에뮬레이션)으로 설정
  • 30,000px까지만 스크롤하여 무한스크롤 대비
  • 레이어 팝업 자동 닫기 기능 추가

✔ 전체 코드

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# 시나리오
# 1. 지정한 URL 기준 하단까지 스크롤
# 2. 인피니티 스크롤인 경우 30,000 길이까지만 스크롤

mobile_emulation = { "deviceName": "iPhone 12 Pro" }

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--incognito") #시크릿모드
chrome_options.add_experimental_option("detach", True)
chrome_options.add_argument("--auto-open-devtools-for-tabs")
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)

driver=webdriver.Chrome(options=chrome_options)

# 대상 URL 설정 
url = 'https://shopping.naver.com/home'
driver.get(url)
# 인피니티 스크롤 대처 변수 설정
endScroll = 30000

#대상 URL(네이버 쇼핑) 초기 레이어팝업 닫기 클릭하기
driver.find_element(By.XPATH,'//*[@id="gnb-header"]/div[4]/div/div/button[2]').send_keys(Keys.ENTER)

time.sleep(1)

#스크롤 함수
def webScroll(i_present_location):
    print("#####Start Scroll#####")
    time.sleep(1)
    #스크롤 시작지점 초기화
    from_scroll_height = 0
    #스크롤 종료지점 초기화
    to_scroll_height = 500
    last_height = driver.execute_script("return document.body.scrollHeight")    
    
    while True:
        #scroll 진행
        driver.execute_script("window.scrollTo("+ str(from_scroll_height) + "," + str(to_scroll_height) + ")")
        time.sleep(1)
        #현재 스크롤 위치
        present_location = driver.execute_script("return window.pageYOffset")
        #페이지 하단에 위치하면 종료
        if last_height == present_location:
            #하단 메뉴 보이고 나가기
            driver.execute_script("window.scrollTo("+ str(to_scroll_height) + "," + str(from_scroll_height) + ")")
            break
        #현 위치값이 인수로 넘어온 값보다 커지면 종료
        elif present_location > i_present_location:
            driver.execute_script("window.scrollTo("+ str(to_scroll_height) + "," + str(from_scroll_height) + ")")
            break
        else:
            #이동여부 판단 기준이 되는 이전 위치 값 수정
            last_height = driver.execute_script("return window.pageYOffset")
            #하단 위치 +500 씩 이동
            from_scroll_height = to_scroll_height + 1
            to_scroll_height = to_scroll_height + 500
    print("#####End Scroll#####")

#스크롤 함수 호출 : 함수에 넘기는 인수는 무한스크롤에 대처하기 위해 현 스크롤 위치가 인수값을 넘기면 종료시키기 위해 전달
webScroll(endScroll)

time.sleep(5)    
driver.quit()

 

3. 실행 시 예외 처리 (Windows 환경 오류 해결 방법)

 

Selenium을 사용할 때 Windows 환경에서는 driver.get_log("performance")를 실행할 경우

log type 'performance' not found 오류가 발생할 수 있다.

 

✔ 해결 방법

1. 크롬 옵션에서 user-data-dir을 지정

2. 크롬을 --remote-debugging-port=9222 옵션으로 실행

 

✔ Windows에서 크롬을 실행하는 BAT 파일 예제

 

아래와 같이 BAT 파일을 생성 후 실행하면 문제를 해결할 수 있다.

@echo off
start "" "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="C:/chrome-user-data"

 

📌 마무리

 

Selenium을 활용하면 스크롤을 자동으로 조작할 수 있다.

특히 무한스크롤 페이지를 처리할 때 유용하며, 특정 이벤트(예: 이미지 로드) 후 데이터를 추출하는 작업에도 활용할 수 있다.

 

👍 추천 활용 사례

뉴스 기사 사이트에서 전체 내용 로딩

인스타그램, 트위터 등의 피드 자동 스크롤

쇼핑몰 상품 목록 크롤링

 

📚 log type "performance not found" 에러 발생 시 도움받은 블로그

 

[selenium]log type 'performance' not found[Solve] 해결하기

굳이 bs4나 requests를 안쓰고 selenium을 사용하는 이유는 다양하겠지만, 보통 API가 없어서 "반드시 로그인이 필요한 경우"에 로그인 과정을 인위적으로 구현하기 위해서 사용하는 경우가 많다. 이때

mrnoobiest.tistory.com