과제
B2B SaaS 제품을 구축 중인 상황을 가정해 보겠습니다. 고객이 회사 이름 목록을 업로드합니다. 고객은 매출 규모, 임직원 수, 기술 스택, 투자 유치 단계, 주요 연락처, 최근 뉴스가 포함된 정제된 레코드를 기대합니다. 며칠이 아닌 몇 분 내로 반환되기를 기대하며, 데이터가 정확하기를 기대합니다.
데이터는 존재합니다. Crunchbase, 회사의 About 페이지, LinkedIn 회사 페이지, Google Maps, Glassdoor, 지역별 사업자 등록부, TechCrunch 아카이브 등에 흩어져 있습니다. 문제는 이 데이터에 안정적으로 접근하는 것입니다.
소스마다 실패하는 방식이 제각각입니다. Crunchbase는 무거운 클라이언트 사이드 앱을 제공하며 봇이 의심되면 다시 렌더링을 실행합니다. LinkedIn은 공격적으로 rate limit을 적용하고 셀렉터를 패치하는 속도보다 빠르게 DOM을 변경합니다 (한 유명 커뮤니티 게시물에 따르면 기본 Python 스크래퍼는 사이트에서 요청을 거부하기 전까지 약 50개 프로필만 처리 가능한 것으로 벤치마크되었습니다). 기업 웹사이트는 정적 HTML부터 콘텐츠를 표시하기 위해 전체 브라우저가 필요한 단일 페이지 앱(SPA)까지 다양합니다. 지역 디렉터리는 분기마다 레이아웃을 변경하고 국가별 차단 기능을 적용합니다. GroupBWT의 2026년 업계 보고서에 따르면, 일부 업종에서는 크롤러의 10~15%가 봇 탐지 변경 및 DOM 변형에 대응하기 위해 매주 수정 작업이 필요합니다.
결과적으로 5개 소스를 활용하는 깔끔한 구조로 시작했던 데이터 보강 파이프라인은 6개월 후 절반쯤 망가진 스크래퍼, 재시도 큐, 그리고 아무도 열어보지 않는 #scraper-alerts라는 이름의 Slack 채널로 엉망이 됩니다 (자체 스크래퍼 유지 관리의 숨겨진 비용에 대해서는 이전에 다룬 적이 있습니다). 지원 큐에는 데이터 품질에 대한 불만이 쌓여갑니다. 팀에서는 회사 이름을 "다섯 개의 스크래퍼와 기도"로 지었어야 했다는 농담을 하기 시작합니다.
접근 방식
스크래퍼는 잠시 잊어버리십시오. 데이터 보강에서 가장 어려운 부분은 데이터 추출이 아닙니다. 어떤 소스에 어떤 도구, 어떤 proxy, 어떤 재시도 정책이 필요한지, 그리고 무엇을 "정상" response로 볼 것인지를 결정하는 라우팅입니다.
FourA 같은 플랫폼은 타겟팅하려는 세 가지 소스 유형에 직접 매핑되는 세 가지 제품을 제공합니다.
정적 HTML 디렉터리 및 등록부. 대부분의 지역 사업자 등록부와 다수의 기존 B2B 디렉터리는 서버 사이드에서 렌더링됩니다. 여기에는 깨끗한 IP에서 전송되는 빠르고 오버헤드가 적은 HTTP request가 적합합니다. 이것이 바로 Single입니다. URL 하나를 입력하면 response 하나가 출력됩니다. unblocker: true을 추가하면 일반 HTTP 클라이언트를 완전히 차단하는 핸드셰이크 수준의 차단도 통과합니다. Single은 자동으로 Proxy Finder를 통해 라우팅하며 response 최상위 수준에 proxy id(r.proxy)를 반환하므로, 세션 연속성이 필요할 때 후속 호출에서 이를 proxy:"<id>"로 다시 전달하여 동일한 출구를 유지할 수 있습니다.
JavaScript 비중이 높은 SPA. Crunchbase, LinkedIn 스타일의 애플리케이션, 심지어 중간 규모의 기업 사이트조차 단순 HTTP response로는 원하는 데이터를 반환하지 않습니다. 클라이언트에서 렌더링되기 때문입니다. 이때 Browser를 사용합니다. 실제 브라우저가 페이지를 로드하고, JS를 실행한 뒤, 렌더링된 HTML, cookie, 스크린샷을 반환합니다. Single과 마찬가지로 내부적으로 Proxy Finder를 통해 라우팅되므로 별도의 프록시 선택 작업이 필요 없습니다.
검증이 포함된 혼합 소스. FourA API로 보내는 모든 request는 validate 블록을 사용할 수 있습니다. 특정 status code, header 일치 여부 또는 body 내 하위 문자열 일치를 필수로 지정할 수 있습니다. response가 soft-fail(인증을 요구하는 200 페이지, 비어 있는 데이터 셸, 또는 "we're sorry" 안내 화면)인 경우 validator가 이를 거부합니다. 그러면 파이프라인이 동일한 URL을 Browser를 통해 라우팅할 수 있습니다. 이 단 하나의 기능으로 데이터 보강 작업에서 가장 큰 손실을 유발하는 버그, 즉 데이터베이스에 잘못된 데이터를 기록하는 silent failure를 방지할 수 있습니다.
단일 소스 호출의 구조는 다음과 같습니다.
curl -X POST https://api.foura.ai/api/single \
-H "X-API-Key: pk_live_..." \
-d '{
"url": "https://registry.example.com/company/123",
"unblocker": true,
"followRedirects": 5,
"validate": {
"status": { "accept": [200] },
"data": { "fail": ["captcha", "blocked", "access denied"] }
}
}'
JavaScript 비중이 높은 기업 사이트를 위한 Browser 기반 대체 방식:
curl -X POST https://api.foura.ai/api/browser \
-H "X-API-Key: pk_live_..." \
-d '{
"url": "https://www.example-saas.com/about",
"unblocker": true
}'
라우팅 로직은 사용자의 파이프라인에 두고, 안정성은 FourA가 담당합니다. 어떤 소스에 어떤 도구를 적용할지는 사용자가 결정하고, FourA는 해당 도구가 대상에 안정적으로 도달하도록 보장합니다.
Results
공개 베타 기간 동안 사내 스크래퍼에서 FourA 라우팅 파이프라인으로 전환한 여러 팀을 분석했습니다. 패턴은 일관되게 나타났습니다 (베타 코호트 전반에서 확인된 데이터를 기반으로 한 예시 수치):
- 데이터 보강 레이턴시: 캐시된 주거용 라우트 기준 기업당 3~6초에서 중앙값 1.5초 미만으로 감소
- 무소음 실패율 (Silent-failure rate): 데이터베이스에 도달하기 전
validate블록이 소프트 페일을 감지하면서 200 상태 코드의 빈 응답 비율이 약 8%에서 1% 미만으로 감소 - 스크래퍼 유지보수에 투입되는 엔지니어링 시간: 전담 엔지니어 1~2명 분량에서 대부분 조용한 Slack 채널 수준으로 감소
- 첫 시도 성공률 (First-pass success rate): 보호된 디렉터리에서
unblocker: true및 클린 proxy id를 함께 사용할 때 90% 후반대로 상승
주목할 만한 수치가 하나 더 있습니다. 첫 시도 정확도 (올바른 기업의 올바른 데이터 매칭)는 첫 시도 성공률보다 약 4%포인트 뒤처진다는 점입니다. 여기서 얻을 수 있는 교훈은 스크래핑 자체가 어렵다는 것이 아닙니다. 요청한 실제 기업과 반환된 레코드가 일치하는지 여전히 검증해야 한다는 점입니다 (이 패턴에 대해서는 웹 스크래퍼가 계속 깨지는 이유에서 다루었습니다).
중요한 수치는 프록시 풀의 크기나 request 수가 아닙니다. 첫 번째 시도에서 데이터 보강 endpoint가 올바른 데이터를 반환하는 비율과 향후 6개월 동안의 스크래퍼 유지보수 공수 곡선입니다.
Key Takeaway
데이터 보강 파이프라인의 실패는 서서히 진행됩니다. 처음 작성한 스크래퍼는 시작할 때는 문제없어 보입니다. 하지만 소스가 세 개로 늘어나면 밤 11시에 셀렉터를 패치하게 됩니다. 열 개로 늘어나면 고객 기반에 비례하여 증가하는 유지보수 부채를 떠안게 됩니다. 스무 개에 도달하면 팀 내 누구도 다음 소스를 맡고 싶어 하지 않아 새로운 소스 연동을 조용히 중단하게 됩니다.
병목은 소스 자체가 아니었습니다. 병목의 원인은 라우팅이었습니다. 즉, 매번 모든 URL에 대해 올바른 도구, 올바른 proxy, 올바른 검증 규칙을 선택하는 작업입니다. 이 레이어를 직접 한 번 구축하거나 이미 검증된 솔루션에 맡기면, 팀은 셀렉터 파손을 트리아지하는 대신 제품 개발에 집중할 수 있습니다.