파서의 여분의 메가바이트 트래픽은 프록시 제공업체에 대한 지불이거나 한도에 걸리거나 IP 차단의 위험을 의미합니다. Wildberries, Ozon에서 가격을 수집하거나 수백 개의 프록시 주소를 통해 Avito의 광고를 모니터링하는 경우, 트래픽 절약은 프로젝트 예산에 직접적인 영향을 미칩니다. 이 기사에서는 전송되는 데이터 양을 4-5배 줄이면서도 추출된 정보의 완전성과 정확성을 유지하는 구체적인 기술적 방법을 소개합니다.
파서 트래픽이 예산에 미치는 영향
대부분의 프록시 제공업체는 거주지 및 모바일 프록시를 사용량에 따라 요금이 부과되며, 사용 시간에 따라 요금이 부과되지 않습니다. 파서가 Wildberries의 상품 페이지를 완전히 로드하면 — 이미지, 추천 스크립트, 분석 트래커 및 글꼴이 포함되어 — 한 카드당 2-3MB를 지불하게 되지만 실제로 필요한 것은 15-20KB의 텍스트: 이름, 가격, 평점, 재고입니다.
하루에 50,000-100,000개의 카드로 확장할 경우, "모두 로드"와 "필요한 것만 로드"의 차이는 매일 수십 기가바이트의 여분의 트래픽으로 변합니다. 이는 프록시에 대한 비용뿐만 아니라, 목표 사이트에 대한 부하 증가로 이어져, 안티봇 보호에 걸릴 확률이 높아지고 CAPTCHA나 IP의 일시적 차단을 받을 수 있습니다. 트래픽 최적화는 동시에 비용 절감과 차단 위험 감소를 의미합니다.
세 번째 효과가 있습니다: 한 요청에서 전송되는 데이터가 적을수록 요청이 더 빨리 수행됩니다. 이는 병렬성을 증가시켜, 동일한 수의 프록시에서 더 많은 스레드를 실행할 수 있게 하여, Dolphin Anty 또는 AdsPower와 같은 안티디텍트 브라우저가 세션 작업 시 설정한 속도 제한을 초과하지 않도록 합니다.
방법 1: 이미지, CSS 및 글꼴 차단
파서가 헤드리스 브라우저(Playwright, Puppeteer, Selenium)를 통해 작동하는 경우, 트래픽을 2-3배 줄이는 가장 빠른 방법은 DOM의 데이터에 영향을 미치지 않는 정적 리소스의 로드를 차단하는 것입니다. 상품 이미지, 웹사이트 글꼴, 비디오 및 CSS 스타일은 페이지의 70%까지 차지하지만, 텍스트 및 속성 추출에는 전혀 참여하지 않습니다.
from playwright.sync_api import sync_playwright
def block_heavy_resources(route, request):
if request.resource_type in ["image", "media", "font", "stylesheet"]:
route.abort()
else:
route.continue_()
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.route("**/*", block_heavy_resources)
page.goto("https://example.com/product/123")
html = page.content()
browser.close()
Puppeteer에서는 page.setRequestInterception(true)를 통해, Selenium에서는 profile.managed_default_content_settings.images: 2 매개변수를 사용하여 Chrome 프로필을 설정하여 유사한 논리를 구현할 수 있습니다. 실제로 이 설정 하나로 마켓플레이스에서 시각적 콘텐츠와 광고 배너로 과부하된 페이지를 파싱할 때 트래픽을 50%에서 70%까지 즉시 줄일 수 있습니다.
방법 2: 전체 브라우저 대신 HTTP 요청
많은 사람들이 Selenium이나 Playwright를 필요하지 않은 곳에서 사용합니다. 페이지가 데이터를 렌더링하기 위해 JavaScript 실행을 요구하지 않는 경우(이는 "페이지 소스 보기"를 열어 DevTools 대신 쉽게 확인할 수 있습니다), HTML을 직접 requests 또는 httpx 라이브러리를 통해 가져오는 것이 훨씬 유리합니다. 이러한 요청은 메가바이트가 아닌 킬로바이트를 차지하며, 브라우저 렌더링 엔진, 트래커에 대한 네트워크 호출 및 부차적인 리소스를 포함하지 않기 때문입니다.
import httpx
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Accept-Encoding": "gzip, br",
"Accept": "text/html,application/xhtml+xml"
}
proxies = {"http://": "http://user:pass@proxy_host:port",
"https://": "http://user:pass@proxy_host:port"}
with httpx.Client(headers=headers, proxies=proxies, http2=True) as client:
response = client.get("https://example.com/catalog/item/456")
print(len(response.content), "바이트 수신됨")
브라우저 에뮬레이션에서 직접 HTTP 요청으로 전환하면, 사이트가 클라이언트 렌더링 없이 준비된 HTML을 제공하는 경우 트래픽을 3-8배 줄일 수 있습니다. 유일한 주의 사항은 이러한 요청이 실제 사용자와 구별하기 쉽기 때문에, 강력한 안티봇 보호가 있는 사이트의 경우 이 방법을 질 좋은 거주지 프록시와 결합하여 사용하는 것이 좋습니다. 이는 실제 가정용 제공업체의 IP를 제공하여 요청 차단 가능성을 줄입니다.
방법 3: 숨겨진 JSON API를 통한 파싱
거의 모든 현대의 마켓플레이스 — Wildberries, Ozon 및 Yandex.Market을 포함하여 — 상품 카드와 목록을 프론트엔드에서 호출하는 내부 JSON API를 통해 렌더링합니다. 이러한 엔드포인트는 DevTools의 Network 탭에서 XHR/Fetch 유형으로 요청을 필터링하여 찾을 수 있습니다. 일반적으로 이러한 요청 하나는 5-30KB의 순수 데이터로 JSON을 반환합니다: 상품 ID, 가격, 할인, 재고, 평점 — HTML 마크업이나 CSS 없이.
전체 HTML 페이지와 JSON API에 직접 요청하는 것 사이의 전송 데이터 양 차이는 10-15배에 이를 수 있습니다. 추가적인 장점은 JSON을 프로그래밍적으로 파싱하기가 더 쉽다는 것입니다: XPath 선택자가 필요 없고, 딕셔너리 키를 통해 필요한 필드에 접근하기만 하면 됩니다. 단점은 이러한 엔드포인트가 종종 특정 헤더, 세션 토큰 또는 요청 서명 매개변수를 요구하며, 이는 기본 페이지나 모바일 애플리케이션에서 미리 추출해야 한다는 것입니다.
실무자에게 조언
숨겨진 API를 중심으로 파서를 구축하기 전에, 프록시 가로채기 도구(Charles Proxy, Fiddler)를 통해 모바일 버전의 사이트나 애플리케이션을 확인하세요 — 모바일 API는 종종 데스크탑 버전의 사이트보다 더 간결하고 안정적인 JSON을 제공합니다.
방법 4: Gzip 및 Brotli 압축
전체 HTML을 가져와야 하는 경우에도, 올바른 압축을 활성화하면 전송 크기를 60-80% 줄일 수 있습니다. 많은 사용자 정의 파서는 Accept-Encoding: gzip, br 헤더를 전송하지 않기 때문에 서버는 압축되지 않은 응답을 반환합니다. requests 및 httpx 라이브러리는 Gzip 및 Brotli를 자동으로 압축 해제합니다 — 요청 헤더에서 압축 지원을 명시적으로 지정하기만 하면 됩니다.
Brotli는 평균적으로 Gzip보다 텍스트 HTML을 15-20% 더 강하게 압축하지만, 모든 서버가 이 알고리즘을 지원하는 것은 아닙니다 — 두 가지 옵션을 요청하고 서버가 최적의 것을 선택하도록 하는 것이 좋습니다. JSON API의 경우 압축 효과는 더욱 뚜렷합니다: 반복되는 딕셔너리 키("price", "name", "rating")는 거의 완벽하게 압축되어 응답의 무게를 크게 줄입니다.
방법 5: 조건부 요청 및 캐싱
동일한 상품의 가격을 하루에 여러 번 모니터링하는 경우, 검사 사이에 대부분의 카드가 변경되지 않습니다. If-Modified-Since 및 첫 번째 요청 시 받은 ETag 값을 가진 If-None-Match 헤더를 사용하세요. 콘텐츠가 변경되지 않았다면, 서버는 본문이 거의 없는 304 Not Modified 상태를 반환합니다 — 변경되지 않은 페이지에서 트래픽 절약은 95%에 이를 수 있습니다.
import httpx
etag_store = {}
def fetch_with_cache(url, client):
headers = {}
if url in etag_store:
headers["If-None-Match"] = etag_store[url]
resp = client.get(url, headers=headers)
if resp.status_code == 304:
return None # 데이터가 변경되지 않음
etag_store[url] = resp.headers.get("ETag", "")
return resp.content
모든 사이트가 ETag를 올바르게 지원하는 것은 아니지만, 이를 지원하는 사이트의 경우 이 방법은 정기적인 모니터링 시 트래픽을 줄이는 가장 효과적인 방법이 됩니다 — 실제 데이터 변경에 대해서만 비용을 지불하고, 변경되지 않은 콘텐츠를 다시 로드하는 데는 비용을 지불하지 않습니다.
방법 6: 필요한 필드 선택적 파싱
때때로 서버 측에서 들어오는 트래픽을 줄이는 것이 불가능합니다 — 사이트가 요청에 관계없이 전체 페이지를 반환하기 때문입니다. 이 경우 최적화는 처리 단계에서 이루어집니다: 추가 필드를 추출하기 위해 페이지를 다시 로드하지 마세요. XPath 또는 CSS 선택기를 설계하여 DOM을 한 번 통과하면서 가격, 이름, 아티클, 재고, 평점과 같은 모든 필요한 속성을 추출하세요 — 다양한 작업을 위해 동일한 URL에 대해 서로 다른 파서를 사용하여 반복 요청을 보내는 대신에.
또한 중첩 페이지의 탐색 깊이를 제한하는 것이 유용합니다. 가격 모니터링을 위해 카테고리 페이지(상품 목록)에서의 데이터로 충분하다면, 각 상품 카드로 개별적으로 이동하지 마세요 — 이는 중복 트래픽을 발생시키며, 가격과 재고에 영향을 미치지 않는 설명 및 리뷰 외에는 새로운 정보를 제공하지 않는 경우가 많습니다.
방법 7: 크롤링 패턴 최적화
URL 중복 제거는 기본적이지만 종종 무시되는 방법입니다. 마켓플레이스 카탈로그는 동일한 콘텐츠를 가진 여러 링크를 생성하지만, 서로 다른 정렬 매개변수, UTM 태그 또는 세션 ID를 가집니다. 큐에 URL을 추가하기 전에 URL을 정규화(추적 매개변수 제거, 쿼리 매개변수 정렬)하면 대규모 카탈로그를 탐색할 때 10-30%의 중복 요청을 제거할 수 있습니다.
데이터 변경 빈도에 따라 탐색 우선 순위를 정하는 것도 트래픽을 절약합니다: 수요가 높은 상품과 변동성이 큰 가격은 매시간 확인해야 하며, 드문 품목은 하루에 한 번 확인해야 합니다. 이러한 적응형 일정은 모든 카드를 동일한 주기로 균일하게 탐색하는 것보다 요청의 총량을 2-4배 줄이면서도 중요한 데이터의 최신성을 유지합니다.
프록시 전략과의 조화
트래픽 감소는 프록시 유형 선택에 직접적인 영향을 미칩니다. 복잡한 안티봇 보호 없이 직접 HTTP 요청으로 대량의 페이지를 파싱하는 경우, 빠르고 저렴한 데이터 센터 프록시로 충분합니다 — 이는 기가바이트당 낮은 비용으로 높은 전송 속도를 제공합니다. 이는 하루에 수천 개의 카드 파싱 시 매우 중요합니다.
강력한 봇 방어가 있는 사이트의 경우, 실제 사용자 행동을 모방하는 것이 중요하므로 거주지 프록시를 사용하는 것이 좋습니다 — 불필요한 리소스를 차단하는 방법과 결합하면 낮은 트래픽과 높은 신뢰도를 동시에 얻을 수 있습니다. 마켓플레이스의 모바일 버전 API를 통해 파싱이 이루어지는 경우, 데이터가 더 간결하고 안티봇 시스템이 모바일 IP 범위를 기준으로 작동하므로, 차단 위험을 추가로 줄이기 위해 모바일 프록시를 고려해야 합니다.
"요청당 최소 트래픽" + "작업에 적합한 올바른 프록시 유형"의 조합은 인프라 비용을 줄이고 데이터 수집 속도를 높이면서도 신뢰성을 잃지 않게 합니다.
방법 비교 표
| 방법 | 트래픽 감소 | 구현 난이도 |
|---|---|---|
| 이미지/CSS/글꼴 차단 | 50-70% | 낮음 |
| 브라우저 대신 HTTP 요청 | 3-8배 | 중간 |
| 숨겨진 JSON API | 10-15배 | 높음 |
| Gzip/Brotli 압축 | 60-80% | 낮음 |
| 조건부 요청 (ETag) | 변경되지 않은 페이지에서 최대 95% | 중간 |
| URL 중복 제거 및 우선 순위 지정 | 2-4배 | 중간 |
구현 체크리스트
- 목표 페이지가 JavaScript 렌더링을 요구하는지 확인하거나
httpx/requests를 통해 HTML을 직접 가져올 수 있는지 확인하세요. - 브라우저가 필요하다면 헤드리스 브라우저에서 image/media/font/stylesheet 차단을 설정하세요.
- DevTools → Network → XHR/Fetch를 통해 내부 JSON API를 찾으세요.
- 모든 요청에
Accept-Encoding: gzip, br헤더를 추가하세요. - 반복되는 URL에 대한 조건부 요청을 위해 ETag/Last-Modified 저장을 구현하세요.
- 탐색 전에 URL 큐를 정규화하고 중복 제거하세요.
- 데이터의 중요성과 변동성에 따라 적응형 탐색 빈도를 설정하세요.
- 최종 트래픽 프로필에 맞는 프록시 유형을 선택하세요 — 데이터 센터, 거주지 또는 모바일 프록시.
결론
파서 트래픽을 5배 줄이는 것은 순차적으로 방법을 적용하면 현실적인 목표입니다: 불필요한 리소스를 제거하고, 가능한 경우 직접 HTTP 요청이나 JSON API로 전환하고, 압축을 활성화하고, 변경되지 않은 데이터에 대해 조건부 요청을 사용하고, 탐색 패턴 자체를 최적화하세요. 이러한 각 단계는 측정 가능한 효과를 제공하며, 함께 적용하면 마켓플레이스 및 기타 사이트에서 데이터 수집 프로젝트의 경제성을 근본적으로 변화시킵니다.
트래픽 최적화 후에는 새로운 부하 프로필에 맞는 프록시 인프라를 올바르게 선택하는 것이 중요합니다. 대량의 데이터를 빠르고 저렴하게 수집하기 위해서는 데이터 센터 프록시가 적합하며, 강력한 안티봇 보호가 있는 사이트와 작업할 경우에는 거주지 프록시를 사용하여 실제 가정용 제공업체의 IP를 통해 차단 위험을 줄일 수 있습니다.