본문 바로가기

코딩과 AI와 자동화/크롤링

3편. Selenium을 이용한 동적 페이지 처리

반응형

1편에서 웹 크롤링의 개념과 구조,
2편에서 Requests + BeautifulSoup로 정적 페이지 크롤링 실습까지 다뤘습니다.

하지만 실제 서비스에 들어가 보면 이런 경험이 한 번쯤은 있습니다.

  • HTML을 받아서 BeautifulSoup으로 파싱했는데,
    브라우저에서 보이던 목록이 통째로 안 나옴
  • “더 보기”, “스크롤 내리면 자동 로딩” 같은 부분은
    Requests로는 도저히 가져오기 힘듦

이유는 간단합니다. 해당 사이트가 “동적 페이지”,
자바스크립트로 화면을 그리는 방식이기 때문입니다.

 

이때 등장하는 게 바로 Selenium입니다.

  • 실제 브라우저(Chrome, Edge 등)를 띄워서
  • 사람처럼 클릭하고, 스크롤하고, 입력하고, 기다린 뒤
  • 그 결과 화면의 HTML을 가져와 파싱하게 해 주는 도구입니다.

이번 글에서는

  1. 정적/동적 페이지 차이
  2. Selenium의 기본 구조
  3. 간단한 로그인·리스트 수집 예제
  4. Requests/BS4 vs Selenium, 언제 무엇을 쓸지
  5. 다음 편(구글 시트/노션 연동)에서 이어갈 포인트

까지, 입문자가 부담 없이 이해할 수 있는 수준으로 정리해 보겠습니다.


1. 정적 페이지 vs 동적 페이지 – 왜 Selenium이 필요할까?

1) 정적 페이지(Static Page)

  • 서버가 HTML을 한 번에 만들어서 보내주는 형태
  • 브라우저는 거의 “보기만” 하면 끝
  • 뷰어 입장에서 단순해서
    requests.get(url) 한 번이면 필요한 정보가 대부분 HTML 안에 포함

예:

  • 단순 문서·공지 페이지
  • 오래된 홈페이지 구조
  • 블로그 글 상세 페이지 등

2) 동적 페이지(Dynamic Page)

  • 처음에는 빈 틀만 있는 HTML이 오고
  • 브라우저 안에서 자바스크립트가 실행되면서
    API를 호출해 데이터(목록, 댓글, 차트 등)를 가져와 그리는 구조

특징:

  • HTML 소스(view-source)만 보면,
    실제 화면에 보이던 데이터가 비어 있거나 일부만 존재
  • 스크롤 할 때마다 추가 로딩, 더 보기 버튼, 탭 전환 등
    사용자 행동에 따라 내용이 달라짐

 

이런 경우 Requests + BeautifulSoup만으로는

  • 필요한 API 엔드포인트를 역으로 찾거나
  • 복잡한 파라미터/토큰까지 분석해야 해서
    입문자에게는 거의 “리버스 엔지니어링” 수준이 됩니다.

 

그래서 가장 현실적인 선택이:

사람처럼 브라우저를 조작해서 화면을 완성하게 만들고,
그 상태의 HTML을 가져온다”

이고, 그것을 도와주는 도구가 Selenium입니다.


2. Selenium의 기본 구조 이해하기

Selenium의 핵심은 딱 세 가지입니다.

  1. 브라우저 열기 – Chrome/Edge 등을 자동으로 실행
  2. 브라우저 조작 – URL 이동, 클릭, 스크롤, 입력 등
  3. 결과 가져오기 – page_source로 최종 HTML 받아서 파싱

Selenium 4 기준, 가장 기본적인 코드 흐름은 아래와 같습니다.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time

# 1. 브라우저 옵션 설정 (예: 창을 띄우지 않는 headless 모드)
options = Options()
options.add_argument("--headless=new")  # 새 헤드리스 모드

# 2. 드라이버 생성
driver = webdriver.Chrome(options=options)

try:
    # 3. 페이지 열기
    driver.get("https://example.com")
    time.sleep(2)  # JS 로딩 대기 (실전에서는 WebDriverWait 사용 권장)

    # 4. 요소 찾기
    titles = driver.find_elements(By.CSS_SELECTOR, ".post-title")

    for t in titles:
        print(t.text)

finally:
    # 5. 브라우저 종료
    driver.quit()

 

실무에서는 WebDriverWait과 EC(조건)을 함께 써서
“특정 요소가 나타날 때까지 기다렸다가 진행”하는 패턴을 많이 사용합니다.
하지만 첫 입문 단계에서는 위 흐름만 이해해도 충분합니다.


3. Selenium 설치와 기본 설정 (간단 버전)

3-1. 설치

터미널/명령 프롬프트에서:

pip install selenium

Chrome 브라우저 기준으로는

  • 예전에는 따로 ChromeDriver를 설치해야 했지만
  • 최근 Selenium 버전은 대부분 자동으로 드라이버를 관리해 줍니다.
    (단, 환경에 따라 수동 설정이 필요할 수는 있습니다.)

 

3-2. 기본 템플릿 기억하기

Selenium을 쓸 때는 항상 아래 5단계만 기억하면 됩니다.

  1. 옵션 설정 (필요 시 headless, 언어 등)
  2. webdriver.Chrome(...)으로 드라이버 생성
  3. driver.get(url)로 페이지 열기
  4. find_element(s)로 요소 찾고, .text, .get_attribute() 등으로 데이터 추출
  5. driver.quit()으로 브라우저 종료

앞으로 크롤링할 때도 이 템플릿을 복붙해 놓고,
URL·선택자(CSS/XPath) 부분만 바꾸면 대부분 해결됩니다.


4. 실전 1 – 로그인 필요한 페이지 처리 (개념 예시)

주의:
아래 내용은 본인이 계정 권한을 가진 서비스에서
허용된 범위 내 자동화에만 사용해야 합니다.
서비스 이용약관·로봇 정책을 반드시 확인하세요.

예를 들어 “내가 운영하는 관리자 페이지”에 접속해
일별 방문자 숫자를 가져온다고 가정해 봅시다.

4-1. 흐름 설계

  1. 로그인 페이지 열기
  2. 아이디/비밀번호 입력
  3. 로그인 버튼 클릭
  4. 특정 통계 페이지로 이동
  5. 통계 숫자 요소를 찾아 텍스트로 추출

4-2. 코드 개념(축약)

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

driver = webdriver.Chrome()
driver.get("https://example.com/login")

# 1) 로그인 정보 입력
id_input = driver.find_element(By.ID, "user_id")
pw_input = driver.find_element(By.ID, "user_pw")

id_input.send_keys("my_id")
pw_input.send_keys("my_password")

# 2) 로그인 버튼 클릭
login_btn = driver.find_element(By.CSS_SELECTOR, "button.login")
login_btn.click()

time.sleep(3)  # 로그인 처리 대기

# 3) 통계 페이지 이동
driver.get("https://example.com/admin/stats")
time.sleep(2)

# 4) 원하는 숫자 요소 읽기
today_views = driver.find_element(By.CSS_SELECTOR, ".today-views").text
print("오늘 방문자:", today_views)

driver.quit()

 

실제 사이트 구조에 따라 By.ID, By.NAME, By.CSS_SELECTOR 등
선택자만 바꾸면 같은 패턴으로 적용 가능합니다.


5. 실전 2 – 무한 스크롤 페이지에서 리스트 수집

쇼핑몰, 뉴스 리스트, SNS 타임라인처럼

  • 스크롤을 내릴 때마다 추가로 로딩되는 구조

는 Requests만으로 처리하기 까다롭습니다.


Selenium에서는 “스크롤을 몇 번까지 내려라”라고 명령하면 됩니다.

5-1. 스크롤 기본 패턴

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

driver = webdriver.Chrome()
driver.get("https://example.com/list")
time.sleep(2)

# 스크롤을 n번 반복
for _ in range(5):
    # 페이지 맨 아래로 스크롤
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(2)  # 새 데이터 로딩 대기

# 스크롤이 끝난 뒤, 리스트 요소 가져오기
items = driver.find_elements(By.CSS_SELECTOR, ".item-title")

for i in items:
    print(i.text)

driver.quit()

 

5-2. BeautifulSoup와 함께 쓰기

Selenium으로 화면을 완전히 로딩한 뒤,
결과 HTML을 BeautifulSoup에게 넘겨줄 수도 있습니다.

from bs4 import BeautifulSoup

html = driver.page_source
soup = BeautifulSoup(html, "html.parser")

titles = [tag.get_text(strip=True) for tag in soup.select(".item-title")]

 

즉,

동적 로딩 → Selenium
파싱(정제, 텍스트 추출) → BeautifulSoup

이라는 역할 분담이 가능합니다.


6. Requests/BeautifulSoup vs Selenium – 언제 무엇을 쓸까?

정리해 보면 다음과 같습니다.

Requests + BeautifulSoup가 더 나은 경우

  • 단순 HTML 페이지(블로그 글, 공지, 문서 등)
  • 로그인, 스크롤, 버튼 클릭 없이도
    한 번 요청으로 데이터가 다 내려오는 경우
  • 속도·리소스가 중요한 대량 크롤링

장점:

  • 빠르고 가볍다
  • 서버 부하를 상대적으로 덜 준다
  • 코드가 단순하고 유지보수가 쉽다

Selenium이 필요한 경우

  • 로그인, 팝업 닫기, 버튼 클릭 등
    사용자 인터랙션이 필수인 페이지
  • 스크롤할 때마다, 탭을 클릭할 때마다
    데이터가 로딩되는 동적 페이지
  • 자바스크립트로 렌더링된 그래프·차트 등
    단순 HTML 응답에 없는 데이터

단점:

  • 브라우저를 실제로 띄우기 때문에 속도가 느리고 무거움
  • 서버 요청 수도 많아질 수 있음
  • 운영 환경(서버·클라우드)에서 세팅이 더 까다로울 수 있음

 

그래서 실제 프로젝트에서는 보통:

“되면 Requests/BS4로 하고,
안 되면 Selenium을 고려한다”

는 순서로 접근하는 것이 일반적입니다.


7. 크롤링 시 꼭 기억해야 할 법·윤리 가이드

어떤 도구를 쓰든, 아래 원칙은 공통입니다.

  • 서비스 이용약관·robots.txt 준수
  • 서버에 과도한 요청(짧은 간격 대량 요청) 자제
  • 로그인 정보(ID, 비밀번호, 토큰)를 안전하게 관리
  • 개인 정보, 민감한 정보 수집 금지
  • 상업적 이용 시에는 법적 이슈와 저작권을 반드시 확인

특히 Selenium은 실제 사용자를 흉내내기 때문에
“무엇이든 할 수 있을 것 같은 느낌”이 들지만,
허용된 범위 내에서만 사용하는 것이 중요합니다.


8. 다음 편 예고 – “크롤링 결과를 구글 시트/노션과 연동하기”

이번 글에서 우리는

  • 동적 페이지의 개념
  • Selenium 기본 구조와 코드 템플릿
  • 로그인·무한 스크롤 처리 아이디어
  • Requests/BS4와의 역할 분담

까지 살펴봤습니다.

다음 글인
「크롤링 결과를 구글 시트/노션 등과 연동하는 방법」에서는

  • 오늘까지 배운 크롤링 코드로 모은 데이터를
  • 구글 시트·노션 DB에 자동으로 쌓는 방법
  • 나중에 GPT 자동화와 연결하는 아이디어

까지 이어서 정리해 보겠습니다.

반응형