전체 글

대규모 감성 분석을 위한 제품 리뷰 수집

리뷰는 JS 렌더링, 페이지네이션, 안티봇 장벽 뒤에 숨어 있습니다. 감성 분석 모델에 가치 있는 데이터를 제공하기 위해 수집 파이프라인이 갖추어야 할 요소를 소개합니다.

해결 과제

소비자 브랜드는 이제 단일 마켓플레이스의 리뷰 대시보드에만 의존할 수 없습니다. 동일한 SKU가 Amazon에서 하나의 리뷰 점수를 받고, Walmart에서 또 다른 점수를 받으며, Best Buy에서 세 번째 점수를 받고, Trustpilot이나 브랜드 자체 Shopify 스토어에서 또 다른 점수를 받습니다. 제품 팀, 감성 분석 모델, 또는 CX 운영 대기열이 이 중 하나만 보고 있다면, 깨진 거울을 보며 운전하는 것과 같습니다.

이것이 리뷰 문제의 일상적인 형태인 파편화입니다. 리뷰는 존재하지만, 10개의 서로 다른 로그인, 10개의 서로 다른 렌더링 스택, 그리고 10개의 서로 다른 안티봇 대응 체계 뒤에 숨어 있을 뿐입니다. 감성 분류 모델에 매주 데이터를 공급하거나(또는 상위 리스팅에 부정적인 리뷰가 등록될 때 알림을 트리거하기 위해), 이 모든 리뷰를 한곳에 신선하게 모아야 합니다.

리뷰를 수집하는 것은 데이터 문제이기 전에 렌더링 문제입니다. 그리고 대부분의 팀은 이 전반부 작업이 얼마나 큰지 과소평가합니다.

이것이 어려운 이유

2026년의 리뷰 페이지는 2018년의 리뷰 페이지와 완전히 다릅니다. 중요한 모든 정보는 초기 HTML이 로드된 후에 불러옵니다.

  • 리뷰 목록 자체는 브라우저가 셸을 그린 후 JSON을 통해 가져옵니다.
  • 더 깊은 페이지(리뷰 더 보기, 페이지네이션)는 세션이 올바른 cookie를 유지해야 하며, 종종 스크롤 상호작용도 필요합니다.
  • 정렬 필터(최신순, 인증된 구매자만)는 request 서명을 변경합니다. 하나라도 잘못되면 마켓플레이스는 기본 뷰를 제공하는 동시에 미세한 rate limit을 적용합니다.
  • 페이지 전체가 User-Agent를 확인하기도 전에 request의 로우레벨 서명, header 순서, 타이밍을 검사하는 봇 방어 시스템 뒤에 있습니다.

일반 HTTP request로 해당 페이지를 가져오면 빈 셸(리뷰 없음, 결과 없음)만 받게 됩니다. 직접 구축한 headless 브라우저로 가져오면, 브라우저를 유지 관리하고, 출구를 로테이션하며, 마켓플레이스가 안티봇 업데이트를 배포할 때마다 새로운 탐지 규칙에 대응해 패치해야 하는 지속적인 비용을 감당해야 합니다.

해결책

효과적인 패턴은 단일 API endpoint로 호출할 수 있는 브라우저 기반 fetch입니다. 리뷰 URL을 전달하면 페이지를 렌더링하고, JavaScript를 실행하며, 리뷰 페이로드가 하이드레이션될 때까지 기다린 후 DOM을 반환합니다. 세션 세부 정보가 response와 함께 제공되므로 다음 페이지네이션 fetch에서 이를 재사용할 수 있습니다.

FourA의 Browser 제품을 사용하면 Python에서 다음과 같이 작성할 수 있습니다.

import requests

def fetch_reviews(url, api_key, sticky_proxy=None):
    body = {
        "url": url,
        "unblocker": True,
    }
    if sticky_proxy:
        body["proxy"] = sticky_proxy

    r = requests.post(
        "https://api.foura.ai/api/browser",
        headers={"Authorization": f"Bearer {api_key}"},
        json=body,
        timeout=60,
    ).json()

    return {
        "status": r.get("status"),
        "html": r.get("body"),
        "cookies": r.get("cookies"),
        "sticky_proxy": r.get("proxy"),
        "defense_solved": r.get("defenseSolved"),
    }

리뷰 스크래핑에서 중요한 두 가지 세부 사항이 있습니다.

첫째, unblocker: true는 대부분의 마켓플레이스 리뷰 페이지가 사용하는 네트워크 레벨(wire-level) 방어를 처리합니다. 이것이 없으면 리뷰 대신 챌린지 페이지를 받게 됩니다.

둘째, 반환된 proxy 값은 성공적으로 렌더링을 완료한 출구(exit)의 base36 ID입니다. 동일한 제품에 대한 다음 호출에 이 값을 다시 전달하면 페이지네이션이 사용자를 동일한 방문자로 취급합니다. 따라서 1페이지는 잘 로드되는데 3페이지는 아무것도 반환하지 않는 현상의 차이는 대개 세션을 고정(pin)했는지 여부에 따라 결정됩니다.

상위 20개 리뷰의 신선한 주간 스냅샷만 필요한 제품의 경우, 고정 세션을 건너뛰고 각 호출이 자체 출구를 선택하도록 하십시오. 세션 고정은 깊은 페이지네이션이 실제로 중요한 SKU를 위해 아껴두세요.

기대할 수 있는 결과

이 패턴으로 리뷰 수집을 실행하는 팀은 다음과 같은 관점에서 생각해야 합니다.

  • 커버리지: 판매 중인 모든 마켓플레이스의 모든 제품 리뷰를 CX 알림을 위한 일별 주기부터 트렌드 분석을 위한 주별 주기까지 다운스트림이 요구하는 주기에 맞춰 업데이트합니다.
  • 깊이: 마켓플레이스별 SKU당 리뷰의 처음 3~5페이지로, 여기에 실질적으로 활용 가능한 신호가 존재합니다. 5페이지를 넘어가는 뒷부분은 감성 분석 관점에서 대부분 노이즈에 가깝습니다.
  • 신선도: 새로운 리뷰는 월간 내보내기가 실행된 후 2주 뒤가 아니라, 게시된 지 하루 이내에 감성 분석 파이프라인에 도달합니다.
  • 비용 예측 가능성: 렌더링된 fetch당 비용을 지불하므로, 브라우저를 유지 관리하는 데 필요한 팀의 규모가 아니라 관심 있는 SKU 수에 따라 예산이 확장됩니다.

이는 마법 같은 숫자가 아닙니다. 문제의 절반을 차지하는 렌더링 작업을 팀의 업무에서 덜어냈을 때 얻을 수 있는 결과입니다.

이를 전체 마켓플레이스 모니터링 스택과 비교한다면, 리뷰 수집은 감성 분석에 특화된 사촌 격입니다. 동일한 렌더링 능력을 사용하지만 다운스트림이 다릅니다.

핵심 요약

브랜드가 보는 모든 대시보드는 결국 차트로 끝납니다. 하지만 차트는 다운스트림입니다. 업스트림 비용(대부분의 브랜드가 이를 제대로 하지 못하는 이유)은 렌더링 플릿(fleet)입니다. 즉, 차단하기 위해 구축된 방어 시스템에 맞서 15개의 마켓플레이스 표면에 계속 도달하고 활성 상태를 유지하는 비용이며, 이는 엔지니어 3명과 proxy 계약 비용보다 훨씬 저렴해야 합니다.

렌더링 영역이 리뷰 수집 프로젝트를 가로막고 있다면, 바로 그 부분을 구매해야 합니다. 감성 분석 모델, 대시보드, 알림 등은 신선한 리뷰가 들어오기 시작하면 팀에서 반나절 만에 구축할 수 있는 부분입니다.