AI를 활용한 공학적 연구 방법론
Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)
AI를 활용한 공학적 연구 방법론

동적 데이터 수집 +
로그인 자동화

Session 6 / 8

Selenium · Playwright · wait · 로그인 · 세션 · 무한 스크롤

박수현 · aSSIST University · 2026

🎨 이미지 프롬프트(배경): "A robot hand carefully typing into a login form on a glowing browser, with cookies and session tokens flowing as data streams, teal and purple tones, editorial illustration, 16:9, no text"

LLM · API · 웹스크래핑 기반 연구 데이터 파이프라인
AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

이번 시간을 마치면

개념적으로

  • ✅ Selenium / Playwright 의 공통 4단계 (실행→이동→대기→추출)
  • Implicit / Explicit / Fluent Wait 의 차이
  • 세션·쿠키의 흐름과 로그인 후 보존 방법
  • 무한 스크롤 의 종료 판단 패턴

실습으로

  • ✅ Chrome 자동화로 books.toscrape 50페이지 순회
  • ✅ 네이버 금융 토론 댓글 추출
  • ✅ 로그인 후 쿠키를 requests 로 옮기기
  • ✅ 무한 스크롤 사이트 1곳 자동 종료까지

📖 도서 매핑: Ch.5 §2~3 + Ch.12 §1

PART A

브라우저 자동화가
왜 필요한가

정적 스크래핑의 한계와 동적 웹의 제약

키워드: 정적 웹 · 동적 웹 · 로그인 · JS 렌더링

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

기존 스크래핑(정적)과 오늘 도구(동적)의 차이

S 정적 웹사이트

HTML 완성본
즉시 제공

requests + BS4

바로 파싱
가능

D 동적 웹사이트

JS 실행 후
데이터 표시

브라우저 자동화

Selenium / Playwright
필요

flowchart LR A[Python 코드] --> B[WebDriver / Playwright] B --> C[브라우저 Chrome/Chromium] C --> D[웹사이트] D --> C C --> E[렌더링된 DOM] E --> F[데이터 추출 CSV/DB]
  • 정적 웹: HTML 안에 데이터가 이미 있어 requests/BS4 로 충분
  • 동적·로그인 웹: 브라우저가 JS 실행·쿠키 보유를 해야 화면이 완성됨
  • 그래서 오늘은 브라우저를 코드로 조종하는 방식을 다룸
PART A-1

자동화의
공통 4단계

어느 도구를 쓰든 패턴은 같다

키워드: launch · navigate · wait · extract

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

Selenium vs Playwright — 7개 항목 비교

🦊 Selenium 4

  • 가장 오래된 표준
  • 모든 언어·브라우저 지원
  • 풍부한 자료 / 커뮤니티
  • 약간 느림, API 장황

🎭 Playwright

  • MS 가 만든 후발주자
  • 속도 + 안정성 ↑
  • 한 줄 설치 (pip install playwright)
  • 한 줄 브라우저 다운로드
  • async / sync 양쪽
항목 Selenium Playwright
기본값 wait 명시적 (코드에서 wait 직접 작성) 자동 wait — 액션 직전에 요소 가시·안정 자동 대기
Headless OK OK
멀티탭 OK 컨텍스트 분리 (브라우저 창 단위 격리)
네트워크 가로채기 어려움 쉬움 (route)
학습곡선 완만 약간 가파름

🎯 신규 프로젝트라면 Playwright 추천. 기존 자료/팀 호환 → Selenium.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

Playwright 설치 — pip + 브라우저 2단계

  1. 라이브러리 설치
pip install playwright
  1. 브라우저 바이너리 설치 (최초 1회)
playwright install chromium

💡 개발 환경 정리 팁 - venv 안에서 pip install playwright → 강의별 가상환경 권장 - playwright install chromium 은 용량이 크므로 강의 전 미리 한 번 실행 - Docker 나 서버에서는 Dockerfile 안에서 미리 설치 (도서 예제 참조)

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium참고: examples/ch05/coupang_selenium.py

Selenium vs Playwright — 동일 작업 코드 비교 (books.toscrape)

🅢 Selenium 4

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import (
    WebDriverWait,
)
from selenium.webdriver.support import (
    expected_conditions as EC,
)

# 1) launch (브라우저 실행)
driver = webdriver.Chrome()

# 2) navigate (페이지 이동)
driver.get("https://books.toscrape.com/")

# 3) wait (요소 대기)
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located(
        (By.CSS_SELECTOR,
         "article.product_pod")))

# 4) extract (값 추출)
title = driver.find_element(
    By.CSS_SELECTOR,
    "article.product_pod h3 a"
).get_attribute("title")

print(title)
driver.quit()

🅟 Playwright

from playwright.sync_api import (
    sync_playwright,
)

with sync_playwright() as pw:
    # 1) launch
    browser = pw.chromium.launch()
    page = browser.new_page()

    # 2) navigate
    page.goto(
        "https://books.toscrape.com/")

    # 3) wait
    page.wait_for_selector(
        "article.product_pod")

    # 4) extract
    title = page.locator(
        "article.product_pod h3 a"
    ).first.get_attribute("title")

    print(title)
    browser.close()

🔑 두 코드의 import → launch → navigate → wait → extract → quit 순서는 동일. 함수 이름·인자 표기만 다름.

🎯 4단계는 동일합니다. API만 다른 방식이며, 한 도구를 익히면 다른 도구도 빠르게 학습할 수 있습니다.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

Playwright 로그인 자동화를 만든 프롬프트

💬 Antigravity / ChatGPT 입력 step01_login_save.py

📋 prompt prompts/ch05_prompts.md 📄 example examples/ch05/step01_login_save.py

Python 스크립트 step01_login_save.py 를 만들어 줘.
목적: Playwright 로 사람처럼 한 번 로그인한 뒤,
브라우저 인증 상태 (쿠키·로컬스토리지 포함) 를
auth.json 에 저장해 이후 스크립트가 재사용한다.

요구사항:
1. 라이브러리: playwright (동기 API), python-dotenv
2. 흐름:
   1) load_dotenv() 로 .env 의 MY_ID, MY_PW 읽기
   2) sync_playwright() 컨텍스트로 진입
   3) p.chromium.launch(headless=False)
      — 사람이 화면을 보며 CAPTCHA / 2차 인증 처리
   4) browser.new_context(), ctx.new_page()
   5) https://example.com/login 로 이동
   6) page.fill("#username", ...)
      page.fill("#password", ...)
      page.click("#login-button")
   7) page.wait_for_url("**/mypage**",
                        timeout=60_000)
      — 사람이 2차 인증할 시간 확보
   8) ctx.storage_state(path="auth.json") 저장
   9) "로그인 상태를 auth.json 으로 저장했습니다."
      출력 후 browser.close()
3. auth.json 경로는 현재 디렉토리.
   보안 경고 주석 추가: 이 파일은 쿠키 포함,
   .gitignore 에 등록 필수.
4. 에러 처리: 로그인 대기 타임아웃 시
   예외 메시지 출력 후 정상 종료

환경: Python 3.11, venv. 코드만, 한국어 주석 최소.

🎯 로그인 자동화 시 고려사항

  • headless=False 로 명시 — 사용자가 직접 CAPTCHA 및 2차 인증을 수행할 수 있도록 설정
  • timeout=60_000 (60초) — OTP 입력 시간을 고려하여 60초로 설정
  • storage_state(path="auth.json") — 쿠키와 로컬스토리지·세션스토리지를 모두 저장하여 다음 스크립트에서 로그인 없이 재사용
  • .gitignore 안내 주석 추가auth.json 이 GitHub에 푸시되면 본인 계정이 탈취될 수 있으므로 반드시 .gitignore 에 추가합니다

⚠️ 윤리·법적 책임:
1. 본인 계정과 본인 IP에서만 사용
2. 사이트 이용약관과 robots.txt를 사전 확인
3. 요청 간격에 랜덤 지연(random.uniform(2, 4) 초)을 추가하여 과도한 자동화 요청을 방지
회차 7과 8에서 추가 설명 예정입니다.

📖 출처: ch05_prompts.md §5 — 로그인이 필요한 사이트.

PART B

Wait
Selenium 안정화의 핵심

90%의 셀레니움 에러 = wait 부족

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

3가지 Wait — Implicit / Explicit / Fluent

📋 표

종류 동작 권장
Implicit (암묵적) 모든 find 에 일괄 timeout 시작 시 1회
Explicit (명시적) 특정 조건 충족까지 대기 주력
Fluent (유연한) polling (주기적으로 재확인) 간격까지 제어 까다로운 경우

🎯 권장 패턴

# 1) 한 번 — 안전망
driver.implicitly_wait(5)

# 2) 매번 — 명시적
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable(
        (By.CSS_SELECTOR, "button.submit")
    )
)

# 3) 특수 — 갱신 폴링
WebDriverWait(driver, 30, poll_frequency=0.5).until(
    lambda d: "loaded" in d.find_element(...).get_attribute("class")
)

⚠️ time.sleep(3)최후 수단. 빠른 PC 에선 충분, 느린 CI 에선 부족.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

ExpectedConditions 핵심 5종 — 자주 쓰는 wait 함수

DOM = 브라우저가 만든 HTML 트리 객체. 페이지 로드 후 JS 가 추가하거나 수정 가능.

함수 언제
presence_of_element_located 요소가 DOM 에 존재 (보일 필요 X)
visibility_of_element_located 요소가 눈에 보임
element_to_be_clickable 클릭 가능 (보임 + 활성)
text_to_be_present_in_element 텍스트 등장
staleness_of 요소가 사라짐 (페이지 전환)
from selenium.webdriver.support import expected_conditions as EC

# "더 보기" 버튼이 클릭 가능해질 때까지
btn = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, "button.more"))
)
btn.click()

🎯 클릭은 visibility 가 아니라 clickable — 자주 까먹는 함정.

PART C

로그인 자동화
쿠키 흐름 이해

폼 입력 → 클릭 → 쿠키 추출 → requests

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

세션과 쿠키 — 로그인 후 보존 데이터

🍪 세션·쿠키 흐름

  1. 로그인 폼 제출
  2. 서버가 세션 ID 발급 (= 서버가 기억하는 임시 신분증)
  3. 응답에 Set-Cookie: ... 헤더로 ID 전달
  4. 이후 요청마다 브라우저가 쿠키를 자동 첨부
  5. 서버는 세션 ID로 "이 요청자가 누군지" 인식

🎯 자동화의 두 갈래

  • A. Selenium 으로 끝까지 — 느리지만 단순
  • B. Selenium 으로 로그인만 → 쿠키 추출 → requests 로 빠르게 — 권장

📖 도서 참조: Ch.5 §3 — "세션과 쿠키, 그리고 그들의 사회생활"

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium참고: examples/ch05/step01_login_save.py

본인 계정으로 로그인 후 쿠키 → requests 이전

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests, json

# 1) 셀레니움으로 로그인 (사람 손처럼)
driver = webdriver.Chrome()
driver.get("https://example.com/login")

WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.NAME, "username"))).send_keys("YOUR_ID")
# 입력 필드는 visibility_of_element_located 가 의미상 정확
# (slide 8 참고 — element_to_be_clickable 은 버튼처럼 클릭 대상에)
driver.find_element(By.NAME, "password").send_keys("YOUR_PW")
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type=submit]"))).click()

# 로그인 완료 신호 — URL 변경 또는 본문 변화
WebDriverWait(driver, 10).until(EC.url_contains("/home"))

# 2) 쿠키 추출
sel_cookies = driver.get_cookies()
cookies = {c["name"]: c["value"] for c in sel_cookies}
driver.quit()

# 3) requests 로 빠르게
HEADERS = {"User-Agent": "Mozilla/5.0 ... Chrome/120.0"}
sess = requests.Session()
sess.headers.update(HEADERS)
sess.cookies.update(cookies)

r = sess.get("https://example.com/api/me", timeout=10)
print(r.json())   # 로그인된 사용자 정보

⚠️ 본인 계정 만. 약관 + 회차 7 윤리 체크리스트 통과 필수.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 도서 Ch.5 §2~3Ch.5 §2 Selenium참고: examples/ch05/step01_login_save.py · step02_use_auth.py

로그인 + 쿠키 추출 코드를 만든 프롬프트

💬 ChatGPT / Claude 입력 step01_login_save.py + step02_use_auth.py

📋 prompt prompts/ch05_prompts.md 📄 example examples/ch05/step01_login_save.py

Selenium 으로 로그인 → 쿠키 저장 → requests 로 재사용하는
2단계 스크립트 두 개를 만들어 줘.

step01_login_save.py
1. selenium + webdriver-manager (Chrome) 로 /login 접속
2. ID 입력: visibility_of_element_located 후 send_keys
3. PW 입력 + 제출: element_to_be_clickable 후 click
4. 로그인 완료 신호: WebDriverWait + url_contains("/home")
   (timeout 10s, 실패 시 명확한 메시지 후 종료)
5. driver.get_cookies() → {name: value} dict 변환
6. cookies.json 으로 저장 (UTF-8, indent=2)
7. driver.quit()
8. 자격증명은 .env 의 SITE_ID / SITE_PW 로 (python-dotenv)

step02_use_auth.py
1. cookies.json 을 json.load
2. requests.Session 만들고 sess.cookies.update(...)
3. 사람 User-Agent 1개 헤더에 추가
4. sess.get("/api/me") 응답 .json() 출력
5. cookies.json 없으면 step01 먼저 실행 안내

환경: Python 3.11, venv. 코드만, 한국어 주석 최소.

🎯 이 프롬프트의 결정적 요소

  • 두 파일 분리 — step01(느린 로그인+저장) / step02(빠른 재사용). 매일 쿠키 재사용 패턴
  • 로그인 완료 신호 명시url_contains("/home") 빠지면 빈 쿠키 추출 함정
  • cookies.json 분리.gitignore 추가 필수. PW 도 .env 로 분리
  • user-agent 1줄 — 빠진 채로 호출하면 즉시 차단되는 사이트 다수

💡 본인 계정 만 — 다음 슬라이드 (안티 봇) 와 회차 7 윤리 체크리스트 통과 사이트에서.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

안티 봇 5종 — 자동화 차단 패턴 (캡차·헤드리스 탐지 등)

🛡️ 검출 신호

  1. CAPTCHA (사람·봇을 구분하는 테스트 — Google reCAPTCHA, Cloudflare hCaptcha)
  2. navigator.webdriver = true 검사 (Selenium 이 자동 노출하는 플래그)
  3. 속도 검사 (사람 손과 다름)
  4. IP 평판 (AWS/GCP 같은 데이터센터 IP 는 의심)
  5. 마우스/스크롤 행동 분석

🎯 합법 회피

  • --disable-blink-features=AutomationControlled (navigator.webdriver 플래그를 숨김)
  • 사람 같은 sleep (200~800ms 랜덤)
  • 본인 IP / 본인 계정
  • 캡차는 수동으로 풀고 진행

⚠️ 상업적 자동 우회(서드파티 캡차 풀기 서비스, 봇팜, IP 풀)는 거의 모두 약관 위반 + 형사 위험. 연구는 본인 손이 가능한 범위 안에서.

PART D

네이버 금융
토론·댓글 추출

도서 Ch.12 §1 그대로 따라가기

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

사용자 화면 vs DOM 구조

📺 사용자 화면

종목별 토론 글 리스트.
페이지네이션이 링크가 아닌 JS 로 동작 — 페이지 번호 클릭 시 자바스크립트가 데이터만 갈아끼움.

🛠️ DOM 분석 (DOM = HTML 요소 트리)

각 글이 한 행 (tr).
제목·작성자·날짜·조회수 컬럼.
본문은 상세 페이지 이동 후 로드.

🔑 두 단계 스크래핑: 리스트 → 상세 페이지 → 본문/댓글.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

콘솔로 선택자 검증 — 코드 작성 전 단계

Chrome 콘솔의 $ = document.querySelector (첫 1개), $$ = document.querySelectorAll (전체, Array 반환) — DevTools 내장 단축 함수

💻 콘솔에서

$$("table.type2 tr").length
// → 토론 글 행 개수

$$("table.type2 a.tit")
  .map(a => a.innerText)
// → 제목 리스트

$("a.next").href
// → 다음 페이지

🛠️ DevTools 의 도움

페이지 클릭 시 숨은 GET 발견.
페이지네이션이 ?page=N 쿼리 변경.
requests 로 충분 (Selenium 불필요).

🎯 늘 그렇듯 — API/JSON 우선, Selenium 최후.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium참고: examples/ch05/naver_stock.py

Selenium 으로 5페이지 100건

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd, time

CODE = "005930"  # 삼성전자
URL  = f"https://finance.naver.com/item/board.naver?code={CODE}"
# 주의: 옛 .nhn 도메인은 2020년 폐기 → board.naver 사용

opts = webdriver.ChromeOptions()
opts.add_argument("--headless=new")     # 화면 없이
opts.add_argument("--window-size=1280,900")
driver = webdriver.Chrome(options=opts)

rows = []
try:
    for page in range(1, 6):
        driver.get(f"{URL}&page={page}")
        WebDriverWait(driver, 8).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "table.type2 tr")))
        # 실제 종목토론실 테이블 컬럼: 날짜 / 제목 / 글쓴이 / 조회 / 공감 / 비공감 (6열)
        for tr in driver.find_elements(By.CSS_SELECTOR, "table.type2 tr"):
            tds = tr.find_elements(By.TAG_NAME, "td")
            if len(tds) < 6: continue
            rows.append({
                "date":     tds[0].text.strip(),
                "title":    tds[1].text.strip(),
                "writer":   tds[2].text.strip(),
                "views":    tds[3].text.strip(),
                "agree":    tds[4].text.strip(),
                "disagree": tds[5].text.strip(),
            })
        time.sleep(1.0)   # 매너
finally:
    driver.quit()

df = pd.DataFrame(rows)
df.to_csv(f"naver_discuss_{CODE}.csv", index=False, encoding="utf-8-sig")

🎯 약 15초 / 100건. 사람 손보다 30배 빠름, 매너 sleep 포함.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 도서 Ch.5 §4Ch.5 §2 Selenium참고: examples/ch05/coupang_selenium.py

5페이지 100건 수집을 만든 프롬프트

💬 ChatGPT / Claude 입력 coupang_selenium.py

📋 prompt prompts/ch05_prompts.md 📄 example examples/ch05/coupang_selenium.py

Selenium 으로 검색 결과 페이지 5장을 돌면서 상품 카드
정보를 100건 모아 CSV 로 저장하는 coupang_selenium.py
를 만들어 줘.

요구사항:
1. selenium + webdriver-manager (headful Chrome)
2. 검색어는 함수 인자, default "노트북"
3. 페이지 이동: URL 의 ?page=N 변경 (1..5)
4. 각 페이지 진입 후
   WebDriverWait(driver, 10).until(
       presence_of_all_elements_located(...))
5. 카드 셀렉터(.search-product 가정)는 모듈 상단의
   상수로 분리 — 사이트 DOM 변경 시 한 줄만 수정
6. 카드별 추출: 제목 / 가격(\d 정규식) / 리뷰수(없으면 0)
   / 상품 링크 (a[href])
7. 카드별 try/except — 한 카드 깨져도 나머지 99개 보장,
   skip 카운트 출력
8. CSV 저장: pandas.to_csv("coupang_<검색어>.csv",
   index=False, encoding="utf-8-sig")
9. 페이지 사이 time.sleep(1.0) — 서버 부담 감소

종료 후:
- driver.quit() finally 블록
- 수집 / 스킵 카운트 콘솔 출력

환경: Python 3.11, venv. 코드만, 한국어 주석 최소.

🎯 이 프롬프트의 결정적 요소

  • 셀렉터 상수 분리 — 사이트 DOM 바뀌면 한 줄만 고침. 강의 후에도 학생이 재사용 가능
  • 카드 단위 try/except — N건 중 한 건이 실패해도 나머지를 보장합니다 (스크래핑 실습 기본기)
  • utf-8-sig — 한국어 엑셀 호환 (BOM 자동) — 학회 발표용 시연 안전
  • time.sleep(1.0) — 윤리 5계명의 느린 호출 . 차단 회피 + 서버 부담 ↓

💡 무한 스크롤 사이트면 ?page=N 대신 다음 슬라이드의 Keys.END 반복 패턴으로 교체 — 끝 감지는 prev_h == cur_h.

PART E

무한 스크롤
언제 멈추나

URL 이 안 바뀌는 페이지의 패턴

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium참고: examples/ch05/coupang_playwright.py

무한 스크롤 종료 조건 4가지 — 높이·DOM·시간·스크롤 횟수

신호 코드
요소 개수가 안 늘어남 prev_count == cur_count 두 번 연속 (한 번 같으면 로딩 지연 가능 — 두 번 같아야 끝)
scrollHeight 가 안 변함 prev_h == cur_h (scrollHeight = 페이지 전체 높이 픽셀)
"더 이상 없음" 표시 text_to_be_present_in_element
N건 도달 len(items) >= TARGET
from selenium.webdriver.common.keys import Keys

prev_h = 0
for _ in range(50):                                   # 안전 상한
    driver.find_element(By.TAG_NAME, "body").send_keys(Keys.END)
    time.sleep(1.5)
    cur_h = driver.execute_script("return document.body.scrollHeight")
    if cur_h == prev_h:
        break
    prev_h = cur_h
items = driver.find_elements(By.CSS_SELECTOR, ".feed-item")
print(len(items))

📌 안전 상한 (for _ in range(50)) 빠지면 무한 루프.

PART F

자주 나는 5종
에러 해결

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

Selenium 5대 에러 — 디버그 체크리스트

❌ 에러 → ✅ 해결

에러 원인 해결
NoSuchElementException 아직 안 그려짐 Explicit Wait
ElementClickInterceptedException 다른 요소가 가림 el.scrollIntoView() (요소를 화면 안으로 스크롤)
StaleElementReferenceException Stale = 페이지 갱신으로 옛 요소 참조가 무효화됨 다시 find
TimeoutException wait 짧거나 셀렉터 오타 timeout ↑ + 콘솔 검증
WebDriverException (드라이버) Chrome ↔ driver 버전 차이 pip install -U selenium (Selenium 4.6+ 부터 Selenium Manager 가 driver 자동 관리 — 별도 ChromeDriver 다운로드 불필요)

💡 디버그 팁

  • driver.save_screenshot("dbg.png") — 그 시점 화면
  • driver.page_source — 현재 HTML
  • --headless=new → 처음엔 빼고 눈으로 확인
AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

scrollIntoView — 가려진 요소 클릭 가로채임 해결

btn = driver.find_element(By.CSS_SELECTOR, "button.submit")

# ❌ 위에 sticky header 가 가리고 있을 때
btn.click()  # ElementClickInterceptedException

# ✅ 1) 스크롤로 노출
driver.execute_script("arguments[0].scrollIntoView({block:'center'});", btn)
time.sleep(0.3)
btn.click()

# ✅ 2) JS 직접 호출 (최후)
driver.execute_script("arguments[0].click();", btn)

🎯 두 번째는 사람 행동과 멀어지므로 최후 수단. 봇 검출 가능성.

PART G

미니 프로젝트
Dynamic Shop Demo

대상: https://makemyproject.net/shop/ — 실서비스 경로 기반 동적 수집 실습

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 별도첨부교재 외 보강 자료

미니 프로젝트 — Dynamic Shop Demo (대상·절차)

대상 서비스

  • URL: https://makemyproject.net/shop/
  • 성격: 동적 렌더링 + 로그인 세션 기반 쇼핑몰
  • 데이터: 비로그인 20개 / 로그인 50개(5페이지 x 10개)

왜 이걸 하느냐

  • requests 결과는 초기 HTML 위주라 상품 데이터가 비어 보일 수 있음
  • 브라우저 자동화는 JS 실행 후 최종 DOM을 수집할 수 있음

실습 단계

  1. requests 로 요청 → 한계 확인
  2. 비로그인 상태로 Selenium/Playwright 스크래핑 (20개)
  3. 로그인 후 상품 전체 50개 수집
  4. 상세 페이지 → 후기·판매량 수집
  5. 수집 데이터 시각화 분석
  6. LLM 으로 후기·인사이트 분석

체크 포인트

  • 로그인 전/후 수집량 차이(20 vs 50)
  • 페이지 전환 wait 안정화
  • 세션 유지 확인(/shop/api/me)
AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 별도첨부교재 외 보강 자료

requests vs 브라우저 결과

핵심 차이 — 요즘 쇼핑몰은 HTML 한 번 + JS 가 데이터를 따로 불러와 채우는 2단 구조

구분 requests 브라우저 자동화
HTML 받기
JS 실행
비동기 API 호출
결과 빈 골격 완성된 화면

정적 페이지 → requests + BS4 로 충분
동적·로그인 페이지 → Selenium / Playwright 가 필수

sequenceDiagram participant P as 🐍 Python<br/>(requests) participant S as 🖥️ 서버 participant B as 🌐 브라우저<br/>(Selenium) rect rgb(255, 235, 235) Note over P,S: ❌ requests 만 — 빈 카드 P->>S: ① GET /shop/ S-->>P: ② HTML 골격 Note over P: 🚫 JS 실행 X → 0개 end rect rgb(235, 250, 235) Note over B,S: ✅ 브라우저 — 실제 화면 B->>S: ① GET /shop/ S-->>B: ② HTML 골격 B->>B: ③ JS 실행 B->>S: ④ /shop/api/products S-->>B: ⑤ JSON B->>B: ⑥ DOM 주입 Note over B: ✅ 카드 50개 end
AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 별도첨부교재 외 보강 자료

/shop 기준 인증 절차

  1. 로그인 폼 입력 (user123 / password1234)
  2. POST /shop/api/login
  3. Set-Cookie로 세션 쿠키 발급
  4. 이후 요청에 쿠키 자동 첨부
  5. GET /shop/api/me로 로그인 상태 확인

실습 포인트: - 비로그인 20개 / 로그인 50개 차이 확인 - 로그인 후 페이지네이션/상세 접근 가능 확인

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 별도첨부교재 외 보강 자료

미니 프로젝트 실습 — 6단계 절차

  1. requests 로 요청 → 한계 확인 — 초기 HTML만 받아오면 상품 데이터가 비어 보이는 현상 직접 체험
  2. 비로그인 상태에서 Selenium / Playwright 로 스크래핑 — JS 렌더링 후 DOM 에서 20개 카드 수집
  3. 로그인 후 상품 전체 50개 수집 — 세션 쿠키 유지하며 5페이지 페이지네이션
  4. 상세 상품 페이지로 진입 — 구매자 후기 + 판매량 수집 — 카드 → 상세 이동, 본문에서 텍스트·숫자 추출
  5. 수집 데이터 기반 분석 (시각화) — pandas + matplotlib 으로 가격·평점·판매량 분포·상관 확인
  6. LLM 으로 수집 데이터 분석 — 후기 텍스트 요약·감정·테마 추출, 인사이트 도출

체크리스트: - [ ] 페이지 전환 wait 안정화 (요소 대기 적용) - [ ] 중복/누락 없는 50개 수집 확인 - [ ] CSV 결과를 분석·LLM 단계로 그대로 연결

PART H

Selenium 마무리
자동화 도구의 책임

본인 계정·본인 IP·합법적 트래픽 — 자동화의 3대 안전선.
회차 7 의 개인정보·윤리 주제로 자연스럽게 이어집니다.

AI를 활용한 공학적 연구 방법론·Session 6 · 동적 데이터 수집 실습 (Selenium + 로그인)출처: 바이브코딩 도서2Ch.5 §2 Selenium

오늘의 정리 8가지

  1. 공통 4단계 — launch / navigate / wait / extract
  2. Wait 3종 — Implicit / Explicit / Fluent (주력=Explicit)
  3. EC 의 5함수 — presence / visibility / clickable / text / staleness
  4. 로그인 후 쿠키 → requests 로 이전 = 가장 안정적인 패턴
  5. 안티 봇 5종 — CAPTCHA / webdriver flag / 속도 / IP / 행동
  6. 무한 스크롤 = 4가지 종료 신호 + 안전 상한
  7. 5대 에러 패턴 — 거의 모두 wait + scroll 로 해결
  8. 본인 계정·본인 IP = 회차 7 윤리의 출발

"도구가 강력할수록 합법·매너·책임 의 무게도 커진다."

1 / 34

목차 — Session 6

키보드 단축키 (뷰어)

네비게이션

다음 슬라이드 Space
이전 슬라이드 PgUp
처음 / 끝Home End
목차M

화면

전체화면F
테마 전환D
글자 크게 / 작게+ -
원래 크기 (100%)=
도움말 (열기/닫기)H ?
닫기 (모든 오버레이)Esc
강의 종료 (메인으로)Q

키보드 단축키 (강사)

네비게이션

다음 슬라이드 Space
이전 슬라이드 PgUp
처음 / 끝Home End
목차 (Menu)M
전체화면F

화면

테마 전환D
도움말 (열기/닫기)H ?
닫기 (모든 오버레이)Esc
툴바 펼치기 / 접기[ ]
강의 종료 (메인으로)Q

화면 확대

글자 크게 / 작게+ -
원래 크기 (100%)=
돋보기 (마우스 따라 2× 확대)V

발표자 도구 (PPT 호환)

화이트 화면W ,
블랙 화면B .
레이저 포인터L
펜 모드 ON/OFFP
펜 색상1 2 3 4
펜 자국 지우기 (현재 슬라이드)E
펜 — 마지막 스트로크 취소 (Undo)Z
펜 — 다시 (Redo)R
⏰ 쉬는시간 타이머T
📱 노트뷰 QR (휴대폰 동기화)N

PDF / 종료

PDF 저장 (슬라이드)Ctrl+P
강의 종료 (메인으로)Q X