
처음엔 단순히 생각했다.
"쿠팡 리뷰만 좀 긁어오면 되지, 그냥 requests.get()하고 BeautifulSoup 쓰면 끝 아냐?"
하지만 막상 해보니 아무 데이터도 안 나왔다.
그 이유는 내가 하고자 한 게 단순한 **스크래핑(scraping)**이 아니라, **브라우저 동작을 따라가야만 가능한 크롤링(crawling)**이었기 때문이다.
| 구분 | Web Crawling | Web Scraping |
|---|---|---|
| 목적 | 여러 URL을 따라가며 자동 탐색 | 한 페이지 안에서 정보 추출 |
| 방식 | 링크 수집 → 페이지 이동 반복 | HTML에서 특정 태그 추출 |
| 사용 예 | 뉴스 사이트 전체 아카이브 수집 | 쿠팡 리뷰, 블로그 글 본문 추출 |
| 도구 | Selenium, Puppeteer, Apify 등 | requests, BeautifulSoup, lxml 등 |
실제로는 이 둘이 함께 사용된다.
Headless Browser는 실제 브라우저처럼 동작하지만 **화면(UI)**을 보여주지 않는 브라우저다.
예: Chrome 브라우저를 터미널에서 UI 없이 띄워놓고 자바스크립트 실행 + 클릭 + 스크롤 등 모든 행동을 자동화하는 것.
page.$eval이 먹힘→ 이 모든 걸 처리하기 위해선 Puppeteer 같은 headless browser 기반 크롤러가 필수였다.
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setUserAgent('...'); // 봇 감지 우회
await page.goto(url, { waitUntil: 'networkidle2' });
await page.click('.상품평 탭');
await page.waitForSelector('.리뷰 DOM 요소');
await page.evaluate(() => {
// 스크롤 반복
});
| 항목 | 설명 |
|---|---|
| 🧠 JS 렌더링 가능 | 실제 브라우저처럼 DOM 생성 가능 |
| 🎯 사용자 행동 자동화 | 클릭, 입력, 스크롤 등 제어 가능 |
| 🛡 봇 감지 회피 | User-Agent 조작 + human-like delay |
| 🧱 SPA 대응 | CSR 기반 페이지에도 완벽 대응 |
| 📷 디버깅 | page.screenshot()으로 UI 상태 확인 가능 |
쿠팡 리뷰 데이터는 단순 텍스트가 아니라 동적 비정형 데이터다.
이를 수집하려면 단순 정적 HTML 파싱으로는 절대 부족하다.
이건 단순 크롤링이 아니라, 웹 브라우저 자동화 기반 데이터 엔지니어링에 가까운 작업이었다.
쿠팡처럼 복잡한 구조의 사이트에선
정적 scraping만으론 절대 리뷰 수집이 불가능하다.
이럴 땐 Headless Browser Crawling이 필수다.
다음 글에서는
👉 무한스크롤 구현 방법,
👉 봇 감지 우회 전략,
👉 리뷰 필드 구조 정리 등
좀 더 실전적인 부분을 써보겠다.