Shopify에서 판매하고 있다면 경쟁사 대부분도 Shopify를 쓰고 있을 가능성이 높고, 그들의 가격, 할인, 재고 수준은 스토어를 여는 누구에게나 보입니다. 모니터링 앱은 이를 대시보드로 보여 주지만, 같은 데이터를 관심 있는 스토어와 상품에 맞춰 직접 수집하고 이력을 보관할 수도 있습니다. 이것은 스토어 운영자 한 명의 규모로 하는 가격 인텔리전스이며, Shopify는 대부분의 플랫폼보다 첫걸음이 쉽습니다.
이 가이드에서는 데이터가 어디에 있는지, 상품마다 무엇을 기록할지, 국가별 마켓을 어떻게 비교할지, 그리고 이를 안정적으로 운영하는 방법을 다룹니다.
직접 구축하는 이유
앱은 빠르게 시작할 수 있지만 한계가 있습니다. 보통 경쟁사나 상품 수에 상한이 있고, 앱이 정한 주기로 갱신되며, 원본 이력 데이터는 앱 안에 남습니다. 작은 자체 수집기를 두면 다음을 얻을 수 있습니다.
- 내가 정한 경쟁사 목록. 어떤 앱도 추적하지 않는 작은 스토어까지 포함할 수 있습니다.
- 내가 정한 일정. 예를 들어 세일 기간에는 몇 시간마다, 그 외에는 하루 한 번입니다.
- 내 데이터. 자사 매출과 마진에 연결할 수 있는 스프레드시트나 데이터베이스에 저장됩니다.
대신 약간의 설정과, 요청을 예의 바르고 꾸준하게 유지하는 노력이 필요하며, 이때 프록시가 쓰입니다.
데이터의 위치: 공개된 상품 JSON
대부분의 Shopify 스토어는 공개 카탈로그를 기계가 읽을 수 있는 형태로 게시합니다.
/products.json은 상품과 그 변형을 페이지 단위로 나열합니다. 큰 카탈로그는?limit=250&page=2처럼 붙여 차례로 훑습니다./products/<handle>.json은 하나의 상품을 반환하며, handle은 상품 URL의 마지막 부분입니다./collections/<handle>/products.json은 컬렉션 안의 상품을 나열하며, 한 카테고리만 추적할 때 유용합니다.
각 변형에는 필요한 필드가 들어 있습니다. price, compare_at_price(취소선이 그어진 “정가”), available, sku, 그리고 타임스탬프입니다. 이미지와 스크립트가 포함된 렌더링된 상품 페이지를 불러오는 것보다 훨씬 가볍고, 스토어가 테마를 바꿔도 달라지지 않습니다.
모든 스토어가 이를 열어 두지는 않습니다. 일부는 오류나 비밀번호 페이지를 반환하고, 헤드리스 스토어는 아예 제공하지 않을 수도 있습니다. 그런 경우에는 상품 페이지에 포함된 구조화 데이터를 읽으세요. 이 방법은 HTML을 파싱하는 대신 JSON-LD 추출하기에서 설명합니다.
상품마다 기록할 항목
상품이 아니라 변형을 추적하세요. 다섯 가지 사이즈가 있는 티셔츠는 다섯 개의 변형이며, 경쟁사는 잘 팔리지 않는 사이즈만 할인하는 경우가 많습니다.
변형별, 확인할 때마다 기록할 항목:
- 스토어, 상품 handle, 변형 ID, SKU, 변형 이름(사이즈, 색상).
price와compare_at_price.available(재고 여부).- 확인한 시각, 확인한 국가, 표시된 통화.
도출할 신호:
- 할인 폭:
compare_at_price와price의 차이, 그리고 할인이 시작되고 끝나는 시점. - 가격 변경: 변형의 가격이 바뀔 때마다 이전 값과 새 값.
- 품절: 재고 없음으로 바뀐 변형. 수요가 강하거나 공급에 문제가 있다는 신호인 경우가 많습니다.
- 신규 및 삭제된 상품: 경쟁사가 출시한 상품과 조용히 내린 상품.
변경 사항과 하루 한 번의 스냅샷만 저장하면, 수십 개의 스토어를 추적해도 이력이 작게 유지됩니다.
마켓: 같은 스토어, 국가마다 다른 가격
Shopify Markets를 사용하면 하나의 스토어가 여러 국가에서 현지 통화로, 그리고 종종 다른 가격으로 판매할 수 있습니다. 방문자가 받는 마켓은 보통 위치에 따라 정해지며, /en-ca/ 같은 국가별 하위 폴더나 통화 선택기가 쓰이기도 합니다.
이는 모니터링에서 중요합니다. 한 국가에 있는 하나의 서버에서 모든 것을 수집하면 그 마켓만 보게 됩니다. 미국, 영국, 독일의 구매자가 내는 가격을 비교하려면:
- 판매하는 각 국가의 IP로 스토어에 접속하세요. 그래야 스토어가 현지 구매자에게 보여 주는 마켓을 선택합니다.
- 받은 통화와 가격을 그대로 기록하세요. 환산한 값을 기록하지 않습니다.
- 처음에는 마켓마다 상품 하나를 직접 확인하세요. 렌더링된 페이지와 비교해, 수집한 JSON이 해당 스토어의 현지 가격을 보여 주는지 확인합니다.
대부분의 Shopify 비교에는 국가 단위 타기팅으로 충분합니다. 도시 단위 타기팅은 스토어가 지역별로 배송 옵션이나 재고를 바꿀 때만 의미가 있습니다.
최소한의 수집기
아래 스크립트는 프록시를 통해 한 스토어의 카탈로그를 읽고 각 변형의 가격과 재고를 출력합니다. 스토어와 국가별로 일정에 따라 실행하고 결과 행을 데이터베이스에 기록하세요.
import time
import requests
PROXY = "http://customer-USERNAME-country-us:PASSWORD@p.shifter.io:443"
STORE = "https://competitor-store.example"
def fetch_catalogue(store):
page = 1
while True:
r = requests.get(
f"{store}/products.json",
params={"limit": 250, "page": page},
proxies={"http": PROXY, "https": PROXY},
timeout=30,
)
r.raise_for_status()
products = r.json().get("products", [])
if not products:
break
yield from products
page += 1
time.sleep(2) # stay polite between pages
for product in fetch_catalogue(STORE):
for v in product["variants"]:
print(product["handle"], v["id"], v["title"],
v["price"], v["compare_at_price"], v["available"])
사용자 이름의 country-us 를 바꾸면 다른 마켓의 구매자가 보는 그대로 같은 스토어를 수집할 수 있습니다.
프록시 설정
| 작업 | 로테이션 | 타기팅 |
|---|---|---|
| 카탈로그 일일 스냅샷 | 요청마다 | 마켓의 국가 |
| 세일 기간 주요 상품의 잦은 확인 | 요청마다 | 마켓의 국가 |
| 장바구니 또는 결제 합계 확인 | 스티키 세션 | 마켓의 국가 |
Shopify 스토어는 하나의 주소가 페이지를 요청하는 속도를 제한하며, 매일 같은 스토어를 방문하는 모니터링 서버는 금방 눈에 띕니다. 요청마다 새 IP를 쓰는 레지덴셜 프록시는 확인 작업을 대상 국가의 실제 가정용 회선에 분산시키므로, 스토어는 현지 구매자에게 하듯 응답합니다.
수집을 안정적으로 유지하는 몇 가지 습관:
- 같은 스토어의 페이지 사이에는 1~2초 쉬고, 스토어들을 하루 동안 나눠서 확인하세요.
- 주요 상품은 자주, 전체 카탈로그는 하루 한 번 확인하세요. 대부분의 가격은 시간 단위로 바뀌지 않습니다. 적절한 주기를 정하는 데는 온라인 가격이 얼마나 빨리 바뀌는지에 대한 연구가 도움이 됩니다.
- HTML 응답이나 챌린지 페이지는 데이터가 아니라 실패로 처리하고, 나중에 다시 시도하세요.
더 큰 체계에 맞추는 방법
Shopify 스토어는 대개 전체 그림의 일부일 뿐입니다. 공급업체와 마켓플레이스도 추적한다면, 드롭쉬핑용 프록시 가이드에서 경쟁 스토어와 함께 상품 리서치와 공급업체 모니터링을 다룹니다.
결론
경쟁사 Shopify 스토어를 지켜보는 데 앱은 필요하지 않습니다. 공개된 상품 JSON을 읽고, 각 변형의 가격, “정가”, 재고를 확인 시각 및 국가와 함께 기록하고, 변경 사항만 보관하세요. 각 마켓은 해당 국가의 IP로 수집하고, 로테이션 레지덴셜 프록시를 사용해 매일의 일정이 차단 없이 돌아가게 하세요.