Shopify products.json 스크래핑: 모든 스토어가 노출하는 엔드포인트

HTML 파싱은 잊으세요. 모든 Shopify 스토어는 /products.json에서 깨끗한 JSON을 제공합니다 — 전체 카탈로그, 가격, 변형, 재고. 여기에는 페이지네이션 제한, 속도 향상 트릭, 경쟁자 모니터링으로 전환하는 방법이 포함되어 있습니다.

전자상거래를 스크래핑해 본 사람이라면 누구나 아는 고통: 깨지기 쉬운 CSS 선택자, 중첩된 래퍼 div, 하룻밤 사이에 모든 것을 깨뜨리는 레이아웃. Shopify는 당신에게 탈출구를 제공합니다. 거의 모든 Shopify 기반 스토어는 전체 카탈로그를 깨끗하고 구조화된 JSON으로 반환하는 공개 /products.json 엔드포인트를 노출합니다 — 제목, 핸들, 벤더, 태그, 변형, 가격, 재고 플래그 및 이미지. HTML 파싱도, 헤드리스 브라우저도 필요 없습니다. 이 가이드는 엔드포인트가 작동하는 방식, 실제 페이지네이션 제한, 대형 스토어 크롤링을 극적으로 빠르게 만드는 트릭, 그리고 이를 경쟁자 가격 및 재고 모니터링으로 전환하는 방법을 다룹니다.

모든 Shopify 스토어의 엔드포인트

모든 Shopify 스토어의 루트 도메인에 /products.json을 추가하면 제품의 JSON 목록을 얻을 수 있습니다. 이는 Ajax API를 위해 설계된 데이터와 동일하며, 각 제품은 안정적인 숫자 id, handle, vendor, product_type, tags, variants 배열(각각의 가격, SKU 및 available 불리언 포함), 그리고 이미지가 포함되어 있습니다. 이는 일반적으로 제품 페이지를 스크래핑할 때 필요한 모든 것을 하나의 요청으로 제공합니다.

import requests

url = "https://store.example.com/products.json"
r = requests.get(url, params={"limit": 250, "page": 1}, timeout=15)
products = r.json()["products"]

print(len(products), products[0]["title"])
for v in products[0]["variants"]:
    print(v["sku"], v["price"], v["available"])

두 가지 주의 사항이 있습니다. Shopify는 공개 엔드포인트를 페이지당 250개 제품으로 제한합니다 — 어떤 값을 전달하든 이 제한을 초과할 수 없으므로 limit=1000000을 설정하고 한 번에 모든 것을 가져오라는 조언은 무시하세요. 그리고 일부 스토어는 엔드포인트를 비활성화합니다(맞춤 빌드에서는 가끔 비활성화됨), 그러므로 파이프라인을 구축하기 전에 유효한 응답이 있는지 확인하세요.

끝까지 페이지네이션

250개 제한 때문에 전체 카탈로그는 빈 페이지에 도달할 때까지 페이지를 이동해야 합니다. 단순한 루프는 page를 증가시키고 페이지가 빈 상태로 돌아오면 멈춥니다. 이는 작은 스토어에는 적합합니다 — 몇 백 개의 제품이 있는 상점은 몇 번의 요청으로 충분합니다.

def all_products(base):
    page, out = 1, []
    while True:
        r = requests.get(f"{base}/products.json",
                         params={"limit": 250, "page": page}, timeout=15)
        batch = r.json()["products"]
        if not batch:
            break
        out.extend(batch)
        page += 1
    return out
Shopify products.json 제한을 보여주는 통계 다이어그램: 페이지당 250개 제품 제한, 이진 검색으로 25배 빠른 페이징, 25000개 제품 스토어에서 833페이지
엔드포인트는 페이지당 250개 제품으로 제한됩니다 — 속도는 더 큰 요청이 아니라 마지막 페이지를 빠르게 찾는 데서 나옵니다.

25배 트릭: 먼저 마지막 페이지 찾기

순차 페이징은 큰 스토어에서 느립니다. 병렬화할 수 없기 때문입니다 — 언제 멈춰야 할지 모르기 때문에 모든 페이지가 이전 페이지를 기다립니다. 해결책은 이진 검색입니다: 마지막 비어 있지 않은 페이지를 찾기 위해 페이지 번호를 탐색한 다음 모든 페이지 요청을 동시에 실행합니다. 25,000개 제품이 833페이지에 걸쳐 있는 스토어에 대한 공개 벤치마크에서, 이는 첫 번째 실행에서 약 120초에서 약 12초로, 마지막 페이지 번호가 캐시된 후에는 약 5초로 크롤링 시간을 단축했습니다 — 25배 속도 향상. 동시 요청 폭발이 스로틀링을 유발하지 않도록 회전하는 IP를 통해 탐색을 라우팅하세요.

PROXY = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": PROXY, "https": PROXY}

def last_page(base, hi=1000):
    lo, last = 1, 1
    while lo <= hi:
        mid = (lo + hi) // 2
        r = requests.get(f"{base}/products.json",
                         params={"limit": 250, "page": mid},
                         proxies=proxies, timeout=15)
        if r.json()["products"]:
            last, lo = mid, mid + 1   # go higher
        else:
            hi = mid - 1              # go lower
    return last
# then request pages 1..last_page concurrently

Rob Pike가 말했듯이, n이 작을 때는 복잡한 알고리즘이 느립니다 — 200개 제품 스토어에서는 이진 검색을 건너뛰고 그냥 루프하세요. 이는 수천 개의 카탈로그에서 순차 페이징이 지연될 때 그 가치를 발휘합니다.

풀을 좁히기: 컬렉션 및 단일 제품

항상 전체 카탈로그가 필요한 것은 아닙니다. Shopify는 컬렉션 수준에서 동일한 JSON을 노출합니다: /collections/&lt;handle&gt;/products.json은 해당 컬렉션의 제품만 반환하며, 동일한 방식으로 페이지네이션됩니다. 이는 전체 스토어가 아닌 하나의 카테고리 — 스니커즈, 향수, 단일 브랜드 — 만 추적할 때 효율적인 경로입니다. 그리고 하나의 제품을 검사하려면 URL에 .json을 추가하세요: /products/&lt;handle&gt;.json은 해당 제품의 전체 기록을 제공하며, 모든 변형과 재고 플래그를 포함하여 특정 SKU에 대한 긴밀한 재입고 폴링에 유용합니다.

두 가지를 결합하면 요청량 — 및 대역폭 — 을 줄일 수 있습니다. 전체 엔드포인트로 카탈로그를 한 번 발견하고, 관심 있는 핸들을 저장한 다음, 개별 제품이나 컬렉션을 엄격한 일정에 따라 폴링하세요. 이 패턴은 수백 개의 스토어로 확장되는 모니터와 변경되지 않은 카탈로그를 다시 다운로드하면서 조용히 프록시 예산을 소모하는 모니터의 차이입니다.

경쟁자 모니터링으로 전환하기

실제 가치는 일회성 카탈로그 덤프가 아니라 시간에 따른 차이입니다. 경쟁자의 products.json을 일정에 따라 스냅샷하고, 변형 id로 키를 설정하고, 실행을 비교하여 가격 변경, 신제품 및 재입고를 즉시 포착하세요. availableprice는 각 변형에 존재하기 때문에, 제품 페이지를 건드리지 않고도 재고 및 가격 신호를 얻을 수 있습니다.

def snapshot(base):
    rows = {}
    for p in all_products(base):
        for v in p["variants"]:
            rows[v["id"]] = {
                "product": p["title"],
                "sku": v["sku"],
                "price": v["price"],
                "available": v["available"],
            }
    return rows

# diff today's snapshot against yesterday's to flag price + stock moves
def changes(old, new):
    for vid, cur in new.items():
        prev = old.get(vid)
        if prev and (prev["price"] != cur["price"] or prev["available"] != cur["available"]):
            yield cur["sku"], prev, cur

이는 경쟁자 가격 모니터링드롭쉬핑 연구의 중추입니다 — 둘 다 여러 스토어에서 동시에 스냅샷 및 차이 패턴에 의존합니다.

Shopify 스크래핑을 위한 빠른 데이터센터 프록시 얻기

Shopify products.json 파이프라인의 흐름 다이어그램: 엔드포인트에서 회전 프록시 게이트웨이로, 변형 JSON 파싱으로, 모니터링을 위한 스냅샷 차이로
일정에 따라 스냅샷을 찍고, 변형을 비교하면, 추적하는 모든 스토어에서 실시간 가격 및 재입고 알림을 받을 수 있습니다.

실제로 필요한 프록시

products.json 엔드포인트는 공개 JSON이며, 강화된 결제 흐름이 아니므로 관대합니다 — 하지만 수백 개의 스토어를 스크래핑하거나 일정에 따라 하나를 두드리면 IP당 속도 제한에 도달할 것입니다. 경제적인 해결책은 회전이 가능한 빠른 데이터센터 프록시입니다: 저렴하고 빠르며, 요청을 IP에 분산시켜 단일 IP가 스로틀링되지 않도록 충분합니다. 데이터센터 범위를 완전히 차단하는 스토어에는 주거 IP를 예약하세요. products.json을 비활성화하고 렌더링된 페이지나 봇 보호 뒤에 카탈로그를 숨기는 스토어에는 렌더링 및 회전을 제공하는 Scraper API가 더 깔끔한 대안입니다. 우리의 데이터센터 프록시를 언제 사용할지에 대한 가이드는 결정을 다룹니다.

자주 묻는 질문

Shopify 스토어에서 모든 제품을 JSON으로 어떻게 얻나요?

스토어의 도메인에서 /products.json을 요청하고 ?limit=250&page=N을 추가한 후, 페이지가 빈 제품 배열을 반환할 때까지 page를 증가시키세요. 각 응답은 변형, 가격, SKU 및 재고 플래그가 포함된 최대 250개의 제품을 보유합니다. 대형 카탈로그의 경우, 마지막 페이지를 이진 검색하고 페이지를 동시에 가져오세요.

Shopify products.json의 제한은 무엇인가요?

공개 엔드포인트는 페이지당 250개 제품으로 제한됩니다 — limit이 수용하는 최대 값입니다. 더 큰 숫자를 전달해도 더 많은 결과를 반환하지 않으며, 여전히 카탈로그를 페이지네이션해야 합니다. 이는 Shopify의 엄격한 제한이므로, 한 번의 요청으로 모든 것을 가져오려 하지 말고 페이지네이션을 계획하세요.

Shopify products.json을 스크래핑하는 것이 합법인가요?

엔드포인트는 로그인 없이 공개적으로 이용 가능한 제품 데이터를 제공합니다, 그리고 미국 법원은 일반적으로 공개 데이터를 스크래핑하는 것을 지지해 왔습니다. 그렇다고 하더라도, 스토어의 서비스 약관을 존중하고, 개인 데이터를 피하고, 서버를 과부하시키지 마세요. 이는 일반 정보이며 법적 조언이 아닙니다 — 사용 사례와 관할권에 대한 구체적인 사항을 확인하세요.

왜 products.json이 404 또는 빈 응답을 반환하나요?

스토어가 Shopify에 있지 않거나, 상인이 사용자 정의 빌드에서 엔드포인트를 비활성화했기 때문입니다. 일부 스토어는 하나의 IP에서 반복된 요청을 제한하기도 하며, 이는 오류처럼 보일 수 있습니다. 스토어가 Shopify인지 확인하고, IP를 회전시키고, 요청 사이에 지연을 추가한 후 엔드포인트가 사라졌다고 가정하세요.

products.json 엔드포인트는 Shopify 스크래핑을 선택자 조정 작업에서 깨끗한 JSON 가져오기로 전환합니다: 전체 카탈로그, 가격 및 재고를 하나의 URL로, 페이지당 250개, 이진 검색으로 빠르게 크롤링하고, 경쟁자 모니터링으로 쉽게 차이 분석할 수 있습니다. 한 번 발견하고, 중요한 컬렉션 및 제품을 폴링하고, 회전하는 데이터센터 IP에 요청을 분산시키면, 한 번의 차단된 실행 없이 수백 개의 스토어를 일정에 따라 추적할 수 있습니다 — HTML 파서도, 헤드리스 브라우저도, 관리해야 할 깨지기 쉬운 선택자도 필요 없습니다.

QuantumProxies와 함께 Shopify 스크래핑 시작하기