학습일지

[스나이퍼팩토리] 한컴AI아카데미(26.06.08) Selenium

cd-record 2026. 6. 9. 09:47

 

Selenium

# Selenum이란?

Selenium은 원래 웹 애플리케이션의 테스트를 자동화하기 위해 만들어진 도구입니다. 하지만 실제 브라우저를 제어할 수 있다는 강력한 기능 덕분에, 최근에는 동적 크롤링에 가장 많이 활용

 

왜 Selenium인가?

  • 정적 크롤링(requests+BeautifulSoup): 서버가 응답하는 HTML 원문만 가져옵니다. 자바스크립트로 데이터를 불러오는 경우 데이터를 수집할 수 없습니다.
  • 동적 크롤링(Selenium): 실제 크롬 브라우저를 띄워 자바스크립트를 모두 실행한 뒤, 사용자가 보는 최종 화면의 HTML을 가져올 수 있습니다.

# 코드 분석

## 라이브러리별 역할

from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
라이브러리 역할 비유
selenium 웹 브라우저를 직접 제어하는 핵심 라이브러리 운전기사 (브라우저 조종)
webdriver_manager 크롬 버전별 드라이버를 자동 설치/관리 정비소 (차량 관리)
By HTML 요소(태그, 클래스 등)를 찾는 기준 설정 내비게이션 (목적지 검색 기준)
WebDriverWait 특정 조건이 충족될 때까지 대기 신호등 (안전 확보)
expected_conditions 대기 조건(요소가 화면에 나타나는지 등) 교통 법규 (대기 기준)

## 브라우저 환경 설정

options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36')
  • options = webdriver.ChromeOptions()
    • 브라우저 환경 설정을 담을 객체를 생성합니다. 이 객체에 옵션을 하나씩 추가한 뒤 브라우저를 실행할 때 인자로 넘겨줍니다.
  • options.add_argument('--headless')
    • 의미: 헤드리스(Headless) 모드를 활성화합니다.
    • 설명: 화면에 브라우저 창을 띄우지 않고 백그라운드에서 실행합니다. 서버에서 실행하거나, 창이 뜨는 것이 방해될 때 매우 유용합니다. 리소스를 덜 차지하여 속도도 빠릅니다.
  • options.add_argument('--no-sandbox')
    • 의미: 샌드박스 보안 모델을 비활성화합니다.
    • 설명: 리눅스 환경(특히 Docker나 서버)에서 브라우저를 실행할 때 권한 문제로 충돌이 나는 경우가 많습니다. 이를 방지하기 위해 사용하는 옵션입니다. 로컬 PC보다는 리눅스 서버에서 실행할 때 필수입니다.
  • options.add_argument('--disable-dev-shm-usage')
    • 의미: /dev/shm 공유 메모리 사용을 제한합니다.
    • 설명: 리눅스 시스템에서 브라우저가 사용하는 공유 메모리 공간이 부족하면 브라우저가 갑자기 종료되거나 오류가 발생합니다. 이 옵션은 공유 메모리 대신 디스크 공간을 사용하도록 강제하여 브라우저가 튕기는 현상을 방지합니다.
  • options.add_argument('--user-agent=...')
    • 의미: 사용자의 기기 정보를 위장합니다.
    • 설명: 웹 사이트 서버는 접속자가 '사람'인지 '봇(매크로)'인지 판단하기 위해 User-Agent 값을 확인합니다.
      • 기본 Selenium은 HeadlessChrome/... 같은 이름이 노출되어 봇으로 차단당하기 쉽습니다.
      • 위 코드처럼 실제 윈도우 크롬 브라우저의 정보를 입력하면, 서버가 나를 일반 사용자로 인식하게 만들어 차단을 우회할 확률을 높여줍니다.
옵션 주 목적
--headless 화면 미출력, 속도 향상 및 리소스 절감
--no-sandbox 리눅스/서버 환경에서의 권한 오류 해결
--disable-dev-shm-usage 메모리 부족으로 인한 브라우저 비정상 종료 방지
--user-agent 봇 차단 회피, 실제 사용자로 인식하게 설정

## 서비스 및 드라이버 연결

service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
  • ChromeDriverManager().install(): 매번 수동으로 크롬 드라이버를 다운로드할 필요 없이, 현재 내 컴퓨터의 크롬 버전에 딱 맞는 드라이버를 자동으로 내려받아 연결해 줍니다.
  • driver = webdriver.Chrome(service=service, options=options)
    • webdriver.Chrome(...): 위에서 준비한 service(드라이버 경로)와 options(앞서 설정한 헤드리스 모드, 유저 에이전트 등)를 가지고 실제 크롬 브라우저 프로세스를 실행합니다.
    • driver: 이제 이 변수를 통해 모든 것을 수행합니다. driver.get(url)을 하면 사이트에 접속하고, driver.find_element(...)를 하면 요소에 접근합니다.

여기까지 고정적으로 사용


 

## 명시적 대기와 액션

WebDriverWait(driver, 10).until(
    # EC.presence_of_element_located: 특정 요소가 DOM에 존재하는지 확인
    # 10초 동안 기다리면서 'li.bx .view_wrap' 요소가 나타날 때까지 대기
    # 10초가 지나도 요소가 나타나지 않으면 TimeoutException 예외 발생
    # EC.presence_of_element_located((By.CSS_SELECTOR, 'li.bx .view_wrap'))
    EC.presence_of_element_located((By.CSS_SELECTOR, '...')))
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  • 왜 필요한가요? 웹 페이지는 HTML을 다 불러오기도 전에 자바스크립트가 데이터를 늦게 채워 넣는 경우가 많습니다. WebDriverWait는 "데이터가 완전히 나타날 때까지 기다려!"라고 명령하는 것이고, execute_script는 웹페이지의 '맨 아래'까지 스크롤을 강제로 내려서 '숨겨진 콘텐츠'를 불러오게 만드는 동작입니다.
  • time.sleep()처럼 무작정 기다리는 것이 아니라, 특정 요소가 나타날 때까지 최대 10초를 기다립니다. 요소가 나타나면 즉시 다음 코드로 넘어가므로 효율적입니다.

## 데이터 수집 및 구조화

items = driver.find_elements(By.CSS_SELECTOR, '.클래스명')
for item in items:
    title = item.find_element(By.CSS_SELECTOR, '태그').text
    # ... 리스트에 추가 ...

 

  • find_elements(복수형): 페이지 전체에서 조건에 맞는 모든 리스트를 가져옵니다.
  • find_element(단수형): 위에서 가져온 각 아이템 내부에서 세부 데이터만 쏙쏙 뽑아냅니다.

 

 

 

 

 

 

 

 

 

 

느낀점

 

 

크롤링을 배우면서 정적인 요소만 가져오다가 동적인 부분을 가져오려고 하니까 쉽지 않았다. 아무래도 selenuim이 익숙하지 않아서 그런 것 같다. 오늘은 selenuim에서 sleep부분만 사용해보았다. 다른 사람들은 selenuim이 편한다고 하는데 난 아직까지 편하진 않은 것 같아. selenuim 라이브러리를 많이 사용해봐야할 것 같다.

 

 

 

 

 

 

 

 

 

 

 

 

——————————————————————————

본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.