Skip to main content

Command Palette

Search for a command to run...

[Project] 날씨에 맞는 옷 추천 프로젝트: Selenium은 정말 필요한 선택이었을까? - 크롤링 삽질 기록

Updated
4 min read
[Project] 날씨에 맞는 옷 추천 프로젝트: Selenium은 정말 필요한 선택이었을까? - 크롤링 삽질 기록
S

Nice to meet u :) Im Backend Developer

✍️ 작성하게 된 이유

날씨에 따라 옷을 추천해주는 서비스를 만들면서, 사용자가 입력한 구매 링크에서 옷 정보( 대표이미지, 상품명 )를 불러오는 기능이 필요했다. 처음에 해당 페이지를 동적 페이지로 판단했고, 자연스럽게 Selenium을 도입했다.

하지만 이 결정이 과연 최선이었는지는 수많은 시행착오 끝에야 알 수 있었다.

🕸️ Selenium을 선택한 이유

동적 페이지Jsoup으로 크롤링이 어렵다는 인식으로 처음부터 Selenium을 선택했다. Selenium브라우저 환경을 구동하여 실제 동작하는 것 처럼 행동할 수 있다. 대부분의 사이트들은 동적페이지라는 인식이 있어 해당 라이브러리를 사용했다.

"정적 페이지 = Jsoup, 동적 페이지 = Selenium"이라는 단순한 기준으로 접근했다.

🧪 그런데 실제 사용해보니?

1️⃣ 너무 느리다 (최소 12초)

  • 예시로 29cm 페이지를 보면, 다른 작업이 완료되지 않고 단순히 크롤링 대상 페이지만 로드하는 데도 3초, 전체 요청은 12초 이상 소요되었다.

  • 29cm 페이지 기준 한 번 요청당 12초가 소요됨

2. 서버 환경에선 오류 발생

로컬에서는 정상적으로 작동하던 코드가 AWS 환경에 배포하자 다음과 같은 오류를 뿜기 시작했다.

→ 이는 Selenium WebDriver가 Chrome 브라우저 인스턴스를 생성하지 못해서 발생한 오류였다.

3. OOM (Out Of Memory)까지 발생

  • 상황

    t2.micro(프리티어)인스턴스의 메모리 기준 1GiB 중 70% 이상 사용됨(RAM 용량 부족)

    그에 따라, OOM이 발생하여, 인스턴스가 부하를 버티지 못해 종료하게 됨

    남아있는 부하로 인하여 Rolling 재배포 시도에도 OOM발생으로 문제 발생 이후 재배포 또한 실패하는 상황 발생

  • 원인

    매 요청 마다 Chrome 인스턴스를 매번 새로 생성( 밑 코드 예시 참고 ) → Chrome 브라우저 로드 후 크롤링 진행

    정보를 가져오는 양이 많고 요청이 동시에 여러개 들어오게 되면서 메모리 사용량 폭증

    GUI 없이 실행해도 크롬은 상당한 메모리를 사용

  • 해결 방법

    배포 인스턴스 업그레이드 ( t2.micro → t3a.medium) : vCPU 1→2(2배 증가), 메모리 1GiB→4G1B(4배증가)

    Jsoup으로 변환 ( 밑 방법 참고 )

🧠 크롬이 메모리를 많이 사용하는 이유?

크롬은 각 탭마다 독립적인 프로세스를 생성해 빠른 속도를 확보하는 구조이다. 이 구조는 메모리가 넉넉할 때 다중 탭(하나의 창에 여러 탭 = 프리렌더링)을 활용하여 빠르지만, 메모리가 부족한 서버 환경에서는 오히려 느려지고 오류가 발생할 수 있다.

프리렌더링 기술은 메모리가 넉넉할 땐 빠름, 그렇지 않으면 성능 저하!

🔍 현재 프로젝트 코드로 본 문제점

  • 매번 Chrome 브라우저를 새로 실행하므로, 메모리 낭비

  • Headless 모드라도 자원을 크게 소모

  • 대량 요청 시 리소스 누수 및 OOM 위험 증가

  • 많은 요청이 동시에 들어오면 GC 되기 전에 크롬 인스턴스가 계속 늘어남

🤔 정말 Selenium이 필요했을까?

Selenium의 장점은 분명하다.

✅ 로그인, 클릭, 스크롤 등 사용자 조작 자동화
✅ 자바스크립트 실행 이후 DOM까지 접근 가능
✅ 실제 브라우저와 유사한 환경 제공

하지만, 내가 만든 기능은?

  • 사용자는 URL만 입력

  • 로그인, 클릭, 스크롤 ❌

  • 필요한 데이터( 대표이미지 URL, 상품명 )는 HTML 내 script 태그 안에 모두 존재
    → 즉, 렌더링이 완료될 때까지 기다릴 필요가 전혀 없음

📚 Jsoup으로 전환 결심

🟢 Jsoup이란?

Jsoup은 Java 기반 HTML 파서로, 다음과 같은 특징이 있다:

  • 간단한 API로 HTML 가져오기 (URL, 파일, 문자열 등)

  • DOM 탐색 / CSS 선택자로 데이터 추출

  • HTML 요소, 속성, 텍스트 조작 가능

  • 깨진 HTML도 자동 보정

  • 정제된 HTML 출력 지원

🔎 29cm 페이지 분석

구매 링크로 들어가면 대표 이미지 URL, 상품명 등 필요한 정보는 모두 <script> 태그 내부에 정적 데이터로 존재했다.

👉 즉, Jsoup만으로도 충분히 접근 가능
👉 별도의 렌더링이나 브라우저 제어 필요 없음

🛠️ Jsoup 적용 방법

1️⃣ 의존성 추가

Gradle에서 jsoup 라이브러리 추가

2️⃣ HTML 문서 가져오기

  • tiemout: 대기시간은 15초이다. 15초가 넘어가면 에러가 난다.

  • userAgent: 웹 브라우저가 서버에 요청을 보낼 때 자신의 정보를 담아 보내는 문자열이다.

  • parser.extract(document): html문서 전체를 extranct 함수로 넘겨준다. 각 사이트에 따른 정보 추출을 진행한다.

  • 필자는 Spring Retry를 사용했기에 e 그대로 예외를 던진다.

3️⃣ 원하는 요소 파싱(29cm)

  • Document: HTML 전체 문서 객체

  • Elements: Element들의 리스트

  • Element: HTML DOM 요소 하나

  • 필자는 사이트별 Parser를 따로 두고 파싱함

⚡ 결과: 속도 개선 : 기존 대비 약 40배의 크롤링 시간 감소

대상 사이트기존(Selenium)변경 후(Jsoup)
29cm12초0.3초

✅ 결론

이번 경험을 통해 깨달은 점

"Selenium을 쓰기 전에 진짜로 브라우저 조작이 필요한지 먼저 확인하자!"

단순히 HTML 내 데이터 추출이라면,
가벼운 도구를 사용하는 것이 속도, 안정성, 운영 효율성 모두에서 더 낫다.

출처

  1. ChromeDriver의 메모리 누수현상

  2. Jsoup 공식 문서

More from this blog

[Spring] N+1문제 발생과 분석

✍️ 작성하게 된 이유 옷을 관리하는 서비스를 개발하면서 Cloth 엔티티와 그에 연관된 ClothWithAttributes, Attribute 데이터를 함께 조회하는 기능이 필요했다.그런데 연관 데이터를 조회할 때마다 쿼리가 폭발적으로 증가(N+1 문제) 하며, 성능이 급격히 저하되는 상황을 마주하게 되었다. Spring JPA의 대표적인 문제로 N+1임을 알고있었지만, 해결하는 방법은 Fetch Join밖에 몰랐다. 지연로딩되는 필드를 엔티...

Sep 17, 20256 min read
[Spring] N+1문제 발생과 분석

데이터베이스 기본 개념 정리

1️⃣ 데이터베이스(DB) & DBMS DB (Database): 일정한 규칙(스키마)에 따라 구조화되어 저장된 데이터의 집합. DBMS (Database Management System): DB를 제어/관리하는 시스템 소프트웨어. 특징: 실시간 접근 가능, 동시 공유 가능. 구조: 데이터베이스 → DBMS → 응용 프로그램 → 사용자 2️⃣ 엔티티(Entity) & 릴레이션(Relation) 엔티티: 여러 속성을 가진 "개체"...

Aug 5, 20252 min read
데이터베이스 기본 개념 정리

[Project] 날씨에 맞는 옷 추천 서비스 : 지그재그 크롤링 여정 기록 (1) ChromeDriver를 EC2에 설치하기

✍️ 작성하게 된 이유 무신사, 29cm는 Jsoup으로 충분히 크롤링이 가능했기 때문에, ZigZag도 당연히 Jsoup으로 처리될 것이라 생각했다. 무신사, 29cm와 마찬가지로 필요한 데이터는 모두 <script> 태그 안에 들어있었다. 하지만… 예상은 보기 좋게 빗나갔다. 🧪 현상 ✅ 로컬 크롤링 → 정상 작동 Jsoup으로 script 태그 내에서 대표 이미지와 상품명을 잘 추출 로컬 환경에서는 아무 문제 없이 작동 ❌ A...

Jul 30, 20253 min read
[Project] 날씨에 맞는 옷 추천 서비스 : 지그재그 크롤링 여정 기록 (1) ChromeDriver를 EC2에 설치하기

Soyulia's Blog

49 posts