원격수집에서 가장 자주 부딪히는 벽은 “응답은 200인데 실제 필요한 데이터가 비어 있는” 상황입니다. 콘텐츠가 JavaScript 렌더링 이후에만 채워지거나, 무한 스크롤·라우팅 기반 SPA라면 단순 HTTP 요청만으로는 수집 품질이 떨어집니다.
이 글은 원격수집 관점에서 Selenium WebDriver로 브라우저를 실제 구동해 DOM을 완성한 뒤 데이터를 추출하는 실전 절차를 다룹니다. 특히 실패를 줄이는 핵심인 WebDriverWait 기반 대기 전략, headless 운영 팁, 로케이터 안정화, SPA 수집 포인트, 운영 체크리스트, FAQ까지 한 번에 정리합니다.
Selenium 크롤링이 필요한 이유(원격수집 관점)
requests로 HTML을 받았는데 본문이 비어 있다면, 실제 콘텐츠가 브라우저에서 스크립트로 렌더링되는 구조일 가능성이 큽니다. Selenium은 브라우저를 실제로 구동해 JavaScript가 만든 DOM까지 포함해 페이지를 로드하고, 렌더링이 끝난 뒤 데이터를 추출합니다.
- 원격수집 대상이 JavaScript-heavy(클라이언트 렌더링)인 경우
- 페이지 진입 후 API 호출로 본문이 채워지는 경우
- 무한 스크롤/더보기 버튼으로 콘텐츠가 계속 늘어나는 경우
- 라우팅 기반의 SPA 크롤링이 필요한 경우
핵심 원칙은 간단합니다. “페이지가 열렸는가”가 아니라 “최종 DOM에 내가 필요한 데이터가 존재하는가”를 성공 조건으로 잡습니다. 이 기준이 흔들리면 원격수집은 재시도/예외 처리가 늘고, 운영 비용이 커집니다.
JavaScript 렌더링이 수집을 어렵게 만드는 이유
정적 요청만으로는 “초기 HTML 껍데기”만 오고, 핵심 데이터는 스크립트 실행 이후에야 화면에 나타나는 경우가 많습니다. 원격수집은 결국 렌더링 이후의 상태를 기준으로 수집해야 품질이 나옵니다.
- 렌더링 이후에 생성되는 DOM: 초기 HTML에는 없고, 스크립트 실행 후 나타남
- 비동기 로딩: 특정 API 응답이 늦으면 요소가 늦게 생성됨
- 클라이언트 라우팅(SPA): URL 이동이 네비게이션이 아니라 상태 변화로 발생
따라서 Selenium을 쓸 때는 “페이지 로드 완료” 같은 모호한 신호보다, 타깃 요소가 준비됐는지를 중심으로 기다립니다. 이 철학이 그대로 WebDriverWait 설계로 연결됩니다.
Selenium WebDriver 설정(기본)
원격수집에서 Selenium을 안정적으로 돌리려면, 실행 환경을 고정하고(브라우저/드라이버 버전, 옵션), 실패 시 증거를 남기는 습관이 필요합니다. “어쩌다 한 번” 성공하는 수집은 운영에서 의미가 없습니다.
기본 설정 체크
- 브라우저 드라이버 준비: 설치된 브라우저와 드라이버 버전을 맞춘다
- 실행 옵션 정리: headless 여부, 창 크기, 다운로드 동작, 사용자 에이전트
- 타임아웃 전략: 페이지 로드/스크립트/명시적 대기(Explicit Wait)를 구분한다
원격수집 관점 운영 팁
- 대상 사이트별로 “필수 로드 요소”를 1~2개 지정하고, 그 요소를 기준으로 성공/실패를 판정한다
- 실패 시 원인 확인을 위해 페이지 타이틀, 현재 URL, 스크린샷/HTML 저장을 자동화한다
- 수집 실패는 숨기지 말고, 재현 가능한 로그(시간/단계/대기 조건)를 남긴다
원격수집에서 가장 중요한 대기 전략: WebDriverWait
동적 페이지는 요소가 “나중에” 등장합니다. 원격수집에서 가장 흔한 실패 원인은 고정 sleep으로 타이밍을 맞추려다, 느린 날/빠른 날/부분 로딩/재시도 상황에 동시에 무너지는 것입니다.
대기 전략 원칙: DOM에 데이터가 존재하는지로 판정
- 성공 조건을 “페이지 열림”이 아니라 “타깃 데이터 요소 존재/가시성/텍스트 포함”으로 둔다
- 대기는 길게 1번이 아니라, 짧은 기준을 여러 단계로 쪼개서 원인을 식별한다
- 실패 시 재시도 전에 현재 URL/타이틀/DOM 일부를 로그로 남긴다
원격수집 체크 포인트
- 대기 대상(로케이터)은 CSS/속성/텍스트 패턴이 안정적인 것을 고른다
- 로딩 스피너, skeleton UI 같은 “로딩 종료 신호”도 함께 본다
- 동적 리스트는 “첫 아이템 1개가 준비되었는가”로 기준을 둔다
headless 브라우저 실행과 안정성 팁
headless는 서버/컨테이너 환경에서 원격수집을 자동화할 때 필수에 가깝습니다. 다만 화면이 없다는 이유로 뷰포트/렌더링/사용자 이벤트가 달라질 수 있으니, 수집 성공 조건을 더 명확히 잡아야 합니다.
- 창 크기(뷰포트)를 고정해 반응형 레이아웃 변화를 줄인다
- 동일한 실행 옵션을 환경별로 통일해 재현성을 올린다
- 실패 시 스크린샷/HTML 저장을 기본값으로 둔다
무한 스크롤(동적 로딩) 수집 패턴
무한 스크롤은 “스크롤 → API 호출 → DOM 증가”의 반복입니다. 원격수집 관점에서는 수집 종료 조건을 명확히 두지 않으면 중복/누락/무한 루프가 생깁니다.
종료 조건을 먼저 결정
- 목표 건수 도달
- 새로 추가된 아이템이 없을 때
- 더보기 버튼 비활성/끝 메시지 노출
중복 방지
- 아이템 고유키(링크/ID/제목+날짜)를 기준으로 set으로 중복을 제거한다
- 페이지가 갱신되거나 정렬이 바뀌는 경우, 수집 순서를 보장할 수 있는 키로 정렬한다
SPA 크롤링: 라우트·메타·404를 같이 본다
SPA는 URL이 바뀌어도 전체 페이지 로드가 없고, DOM 일부만 바뀌는 경우가 많습니다. 원격수집에서는 “라우트 변경이 끝났는지”와 “필요한 DOM이 새로 채워졌는지”를 분리해서 확인해야 합니다.
- URL 변경 또는 라우트 상태 변경을 관찰한다
- 새 화면의 핵심 요소(제목/본문/리스트)가 준비될 때까지 기다린다
- 404/권한 없음 같은 에러 화면도 탐지해 정상 데이터와 분리한다
신뢰도/유지보수: 로케이터·구조·테스트 습관
원격수집 운영 비용은 “코드 작성 시간”보다 “깨졌을 때 복구 시간”이 지배합니다. 따라서 로케이터를 안정적으로 설계하고, 실패의 증거를 자동 저장하고, 재현 가능한 테스트 루틴을 만드는 것이 핵심입니다.
로케이터(Locator) 설계
- 가능하면 데이터 속성(data-*)이나 의미 있는 고유 속성을 우선한다
- 깊은 DOM 경로(부모/자식 과도 의존)는 레이아웃 변경에 취약하다
- 텍스트 기반 선택은 언어/문구 변경에 약하니 보조로만 쓴다
장애 대응 루틴
- 실패 시: 현재 URL, 타이틀, 스크린샷, HTML 덤프를 남긴다
- 재시도는 횟수 제한과 백오프를 둔다
- 사이트별로 성공 조건(필수 요소 1~2개)을 문서화한다
원격수집 Selenium 크롤링 체크리스트
- 원격수집 성공 조건(필수 요소 1~2개)을 정의했다
- WebDriverWait 대상을 “최종 DOM의 데이터 존재” 기준으로 잡았다
- headless 환경에서 뷰포트/옵션을 고정했다
- 무한 스크롤은 종료 조건과 중복 제거 키를 정의했다
- SPA는 라우트 전환 완료 + 새 DOM 준비를 분리해 확인한다
- 실패 시 스크린샷/HTML/URL/타이틀 로그를 자동 저장한다
- 로케이터는 안정적인 속성(data-* 등) 우선으로 설계했다
FAQ
Q. 원격수집에서 sleep을 완전히 없애야 하나요?
핵심은 “sleep을 없애기”가 아니라, WebDriverWait로 성공 조건을 명확히 만드는 것입니다. 꼭 필요한 경우에만 짧고 제한적인 sleep을 보조로 쓰고, 판정은 DOM 기준으로 합니다.
Q. 원격수집에서 가장 먼저 확인할 점은?
요소가 늦게 뜨는지, 아예 다른 API로 채워지는지, SPA 라우팅인지부터 구분하세요. 그 다음 “필수 로드 요소”를 정하고 그 요소를 기준으로 대기를 설계하면 실패율이 빠르게 줄어듭니다.