Endpoint /products.json milik Shopify itu salah satu “jalan pintas” paling umum di dunia data ecommerce. Tinggal tambahkan ke URL toko Shopify mana pun, lalu kamu akan langsung dapat JSON yang sudah terstruktur—tanpa API key, tanpa autentikasi, tanpa perlu bongkar HTML yang berlapis-lapis.
Saya bekerja di tim , jadi saya lumayan sering mikirin cara orang mengekstrak data dari web. Topik scrape Shopify juga terus muncul—tim sales mau pantau harga kompetitor, tim operasional ecommerce mau bandingkan katalog produk, tim procurement mau cari vendor baru. Dengan di Shopify dan platform ini menguasai sekitar , volume data produk yang bisa diekstrak memang besar banget.
Panduan ini akan membahas proses lengkapnya: apa saja yang dikembalikan endpoint ini, cara melakukan pagination untuk ribuan produk, cara menghindari rate limit tanpa kena blokir, dan cara merapikan JSON bertingkat Shopify menjadi CSV atau file Excel yang bersih pakai pandas. Saya juga akan bahas endpoint yang jarang dibicarakan orang lain (/collections.json, /meta.json) dan nunjukin alternatif tanpa coding buat kamu yang ingin langsung pakai tanpa Python.
Apa Itu Endpoint /products.json Shopify (dan Mengapa Ini Memudahkan Scraping)
Setiap toko Shopify punya endpoint publik di {store-url}/products.json yang mengembalikan data produk terstruktur. Tanpa API key. Tanpa OAuth. Tanpa autentikasi apa pun. Kamu cukup tambahkan /products.json ke URL toko, lalu akan keluar JSON berisi semua produk di katalog.
Coba sendiri sekarang: buka atau di browser. Kamu akan lihat JSON yang rapi dan terstruktur berisi judul produk, harga, varian, gambar, tag—semuanya.
Bandingkan dengan cara lain: mengurai HTML tema Shopify yang sangat bertingkat, tidak konsisten antar toko, dan bisa berubah kapan saja saat merchant ganti tema. Ini contoh yang biasanya harus kamu hadapi:
Pendekatan HTML (capek):
1<div class="product-card__info">
2 <h3 class="product-card__title">
3 <a href="/products/classic-blue-jeans">Classic Blue Jeans</a>
4 </h3>
5 <span class="price price--on-sale" data-product-price>$149.00</span>
6</div>
Pendekatan JSON (bersih):
1{
2 "title": "Classic Blue Jeans",
3 "handle": "classic-blue-jeans",
4 "vendor": "Hiut Denim",
5 "variants": [{"price": "149.00", "sku": "HD-BLU-32", "available": true}]
6}
JSON menang dalam hal konsistensi, keandalan, dan kemudahan parsing. Endpoint ini juga mendukung dua parameter penting—?limit= (maksimal 250 produk per halaman, default 30) dan ?page= untuk pagination—yang nanti akan sering kita pakai di kode di bawah.
Perbedaan penting: ini adalah endpoint storefront publik, bukan . Admin API butuh token akses dari pemilik toko dan menyediakan data pesanan, stok, dan informasi pelanggan. Endpoint publik /products.json bersifat read-only untuk data produk dan bisa diakses siapa saja. Saya akan bahas bedanya lebih detail nanti, karena kebingungan soal ini sering banget terjadi di forum.
Catatan penting: tidak semua toko Shopify membuka endpoint ini. Dari pengujian saya, sekitar 71% toko mengembalikan JSON valid (allbirds.com, gymshark.com, colourpop.com, kyliecosmetics.com semuanya berfungsi), sementara beberapa konfigurasi khusus mengembalikan 404 (hiutdenim.co.uk, bombas.com). Cara cek cepatnya simpel: buka {store-url}/products.json di browser dan lihat hasilnya.
Mengapa Scrape Shopify dengan Python? Use Case Bisnis Utama
Kenapa repot-repot? Karena ROI. sekarang memakai scraping harga otomatis untuk competitive intelligence, naik dari hanya 34% pada 2020. Riset juga menunjukkan bahwa . Jadi datanya memang bernilai uang nyata.
Berikut use case yang paling sering saya lihat:
| Use Case | Siapa yang Diuntungkan | Hasil yang Didapat |
|---|---|---|
| Pemantauan harga kompetitor | Tim operasional ecommerce | Melacak perubahan harga, diskon, dan harga pembanding di katalog kompetitor |
| Riset produk & sourcing | Tim procurement / merchandising | Membandingkan fitur produk, varian, material, dan ketersediaan |
| Lead generation | Tim sales | Mengekstrak nama vendor, data brand, dan info kontak dari katalog toko |
| Analisis pasar & kategori | Tim marketing | Memahami komposisi produk, tag, struktur koleksi, dan positioning |
| Pelacakan stok & ketersediaan | Tim supply chain | Memantau status stok di level varian (available: true/false) dari waktu ke waktu |
| Deteksi produk baru | Tim product | Melacak timestamp created_at untuk menemukan peluncuran baru dari kompetitor |
Python adalah pilihan yang paling natural untuk pekerjaan ini. menggunakan Python sebagai bahasa utama, dan ekosistemnya—requests untuk HTTP, pandas untuk manipulasi data, httpx untuk async—membuat proses dari “saya punya URL” menjadi “saya punya spreadsheet” bisa selesai dalam kurang dari 80 baris kode.
Referensi Lengkap Field products.json: Semua Field Dijelaskan
Banyak tutorial lain cuma nunjukin title, id, dan handle, lalu berhenti. Padahal respons JSON Shopify memuat lebih dari 40 field di level produk, varian, gambar, dan opsi. Mengetahui data apa saja yang tersedia sebelum menulis kode akan menghemat waktu kamu dan mencegah scraping ulang di kemudian hari.
Saya menyusun referensi ini dari respons live /products.json yang diambil pada 16 April 2026. Strukturnya konsisten di semua toko yang membuka endpoint ini.
Field di Level Produk
| Field | Jenis Data | Contoh Nilai | Use Case Bisnis |
|---|---|---|---|
id | Integer | 123456789 | ID unik produk untuk deduplikasi |
title | String | "Classic Blue Jeans" | Nama produk untuk katalog dan perbandingan |
handle | String | "classic-blue-jeans" | Slug URL—susun link halaman produk sebagai {store}/products/{handle} |
body_html | String (HTML) atau null | Our best-selling... | Deskripsi produk untuk analisis konten dan riset SEO |
vendor | String | "Hiut Denim" | Nama brand/vendor untuk lead gen atau sourcing |
product_type | String | "Jeans" | Klasifikasi kategori untuk analisis pasar |
created_at | ISO DateTime | "2024-01-15T10:30:00-05:00" | Melacak kapan produk ditambahkan (deteksi peluncuran baru) |
updated_at | ISO DateTime | "2025-03-01T08:00:00-05:00" | Mendeteksi perubahan katalog terbaru |
published_at | ISO DateTime | "2024-01-16T00:00:00-05:00" | Mengetahui kapan produk tayang di storefront |
tags | Array of Strings | ["organic", "women", "straight-leg"] | Analisis keyword/tag untuk SEO, kategori, dan tren |
variants | Array of Objects | (lihat field varian di bawah) | Harga, SKU, dan ketersediaan per varian |
images | Array of Objects | (lihat field gambar di bawah) | URL gambar produk untuk katalog dan analisis visual |
options | Array of Objects | [{"name": "Size", "values": ["S","M","L"]}] | Memahami konfigurasi produk (ukuran, warna, material) |
Field di Level Varian (nested di dalam tiap produk)
| Field | Jenis Data | Contoh | Use Case |
|---|---|---|---|
id | Integer | 987654321 | ID unik varian |
title | String | "32 / Blue" | Nama tampilan varian |
sku | String | "HD-BLU-32" | Pencocokan SKU untuk sistem inventori |
price | String | "185.00" | Pemantauan harga (catatan: ini string, ubah ke float untuk perhitungan) |
compare_at_price | String atau null | "200.00" | Harga awal—penting untuk pelacakan diskon |
available | Boolean | true | Ketersediaan stok (satu-satunya indikator stok publik) |
weight | Float | 1.2 | Analisis pengiriman/logistik |
option1, option2, option3 | String | "32", "Blue", null | Nilai opsi individual |
created_at, updated_at | ISO DateTime | — | Pelacakan perubahan di level varian |
Field di Level Gambar
| Field | Jenis Data | Contoh | Use Case |
|---|---|---|---|
id | Integer | 111222333 | ID unik gambar |
src | String (URL) | "https://cdn.shopify.com/..." | Link langsung untuk mengunduh gambar |
alt | String atau null | "Front view of jeans" | Alt text gambar untuk analisis aksesibilitas |
position | Integer | 1 | Urutan gambar |
width, height | Integer | 2048, 2048 | Dimensi gambar |
Apa yang TIDAK Ada di Endpoint Publik
Satu jebakan penting: inventory_quantity TIDAK tersedia di respons publik /products.json. Field ini dihapus dari endpoint JSON publik pada Desember 2017 demi alasan keamanan. Satu-satunya indikator stok yang kamu dapat adalah field boolean available di tiap varian (true atau false). Untuk mengakses jumlah inventori yang sebenarnya, kamu butuh Admin API yang sudah terautentikasi dengan kredensial pemilik toko.
Sebelum menulis kode scraping, lihat tabel ini dan tentukan field mana yang relevan untuk kebutuhanmu. Kalau fokusmu pemantauan harga, kamu perlu variants[].price, variants[].compare_at_price, dan variants[].available. Kalau kamu ingin lead generation, fokus ke vendor, product_type, dan tags. Saring sesuai kebutuhan—CSV kamu bakal jauh lebih rapi.
Selain products.json: Collections, Meta, dan Endpoint Shopify Lainnya
Hampir tidak ada tutorial yang membahas endpoint ini. Padahal mereka penting untuk competitive intelligence yang serius.
/collections.json — Semua Kategori Toko
Mengembalikan semua koleksi (kategori) di toko beserta judul, handle, deskripsi, dan jumlah produk. Saya verifikasi ini di zoologistperfumes.com, allbirds.com, dan gymshark.com—semuanya mengembalikan JSON valid.
1{
2 "collections": [
3 {
4 "id": 308387348539,
5 "title": "Attars",
6 "handle": "attars",
7 "published_at": "2026-03-29T12:20:32-04:00",
8 "products_count": 1,
9 "image": { "src": "https://cdn.shopify.com/..." }
10 }
11 ]
12}
Kalau kamu ingin memahami bagaimana kompetitor mengatur katalognya, inilah endpoint yang dipakai.
/collections/{handle}/products.json — Produk per Kategori
Mengembalikan produk yang difilter berdasarkan koleksi tertentu. Struktur JSON-nya sama seperti /products.json, tetapi hanya mencakup satu kategori. Ini penting banget untuk scraping level kategori—misalnya kalau kamu hanya ingin memantau koleksi "Sale" atau "New Arrivals" milik kompetitor.
/meta.json — Metadata Tingkat Toko
Mengembalikan nama toko, deskripsi, mata uang, negara, dan—bagian paling berguna—published_products_count. Angka ini memungkinkan kamu menghitung dulu berapa halaman pagination yang dibutuhkan: ceil(published_products_count / 250). Jadi kamu nggak perlu menambah halaman satu per satu sampai dapat respons kosong.
Endpoint Mana yang Sebaiknya Dipakai?
| Yang Anda Cari | Endpoint | Perlu Autentikasi? |
|---|---|---|
| Semua produk (publik) | /products.json | Tidak |
| Produk dalam kategori tertentu | /collections/{handle}/products.json | Tidak |
| Metadata toko + jumlah produk | /meta.json | Tidak |
| Semua koleksi (kategori) | /collections.json | Tidak |
| Data pesanan/penjualan (hanya toko sendiri) | Admin API /orders.json | Ya (API key) |
| Jumlah inventori (hanya toko sendiri) | Admin API /inventory_levels.json | Ya |
Pertanyaan yang sering muncul di forum—"Bisa nggak saya scrape berapa unit yang terjual dari kompetitor?"—jawabannya singkat: tidak bisa. Bukan dari endpoint publik. Data penjualan dan jumlah inventori butuh Admin API yang terautentikasi, artinya kamu harus punya akses pemilik toko. Endpoint publik hanya memberi data katalog produk.

Cara Scrape Shopify dengan Python: Setup Langkah demi Langkah
- Tingkat kesulitan: Pemula
- Waktu yang dibutuhkan: ~15 menit (setup + scraping pertama)
- Yang dibutuhkan: Python 3.11+,
pip, terminal, dan URL toko Shopify yang ingin di-scrape
Langkah 1: Install Python dan Library yang Dibutuhkan
Pastikan kamu sudah menginstal Python 3.11 atau yang lebih baru (pandas 3.0.x membutuhkannya). Lalu install dua library yang kita perlukan:
1pip install requests pandas
Untuk ekspor ke Excel, kamu juga perlu:
1pip install openpyxl
Di bagian atas script, tambahkan import berikut:
1import requests
2import pandas as pd
3import time
4import random
5import json
Seharusnya tidak ada error import saat script dijalankan. Kalau pandas menampilkan error versi, upgrade Python ke 3.12.
Langkah 2: Ambil Data Produk dari /products.json
Berikut fungsi dasar yang menerima URL toko, memanggil endpoint, dan mengembalikan JSON yang sudah diparsing:
1def fetch_products_page(store_url, page=1, limit=250):
2 """Fetch a single page of products from a Shopify store."""
3 url = f"{store_url.rstrip('/')}/products.json"
4 params = {"limit": limit, "page": page}
5 headers = {
6 "User-Agent": "Mozilla/5.0 (compatible; ProductResearch/1.0)"
7 }
8 response = requests.get(url, params=params, headers=headers, timeout=30)
9 response.raise_for_status()
10 return response.json().get("products", [])
Detail penting:
limit=250adalah batas maksimal Shopify per halaman. Default-nya 30, jadi mengatur ini secara eksplisit bisa mengurangi jumlah request sampai 8x.- Header
User-Agent: Selalu gunakan yang realistis. Request tanpa User-Agent lebih gampang memicu sistem anti-bot Shopify. timeout=30: Jangan biarkan satu request menggantung selamanya.
Uji dengan toko yang sudah dikenal:
1products = fetch_products_page("https://allbirds.com")
2print(f"Fetched {len(products)} products")
3print(f"First product: {products[0]['title']}")
Kamu seharusnya melihat output seperti: Fetched 250 products dan judul produk pertama.
Langkah 3: Tangani Pagination untuk Scrape Semua Produk
Satu request maksimal hanya mengembalikan 250 produk. Sebagian besar toko punya lebih dari itu (Allbirds punya 1.420+). Kamu perlu loop lewat halaman sampai dapat respons kosong.
1def scrape_all_products(store_url, delay=1.0):
2 """Scrape all products from a Shopify store, handling pagination."""
3 all_products = []
4 page = 1
5 while True:
6 print(f"Fetching page {page}...")
7 products = fetch_products_page(store_url, page=page, limit=250)
8 if not products:
9 print(f"No more products. Total: {len(all_products)}")
10 break
11 all_products.extend(products)
12 print(f" Got {len(products)} products (total so far: {len(all_products)})")
13 page += 1
14 # Be polite: wait between requests
15 time.sleep(delay + random.uniform(0, 0.5))
16 return all_products
Saat products kosong, berarti kamu sudah sampai akhir.
time.sleep() dengan jitter acak membantu kamu tetap berada di bawah rate limit informal Shopify (~2 request/detik).
Tips: Kalau kamu sudah ambil /meta.json lebih dulu, kamu sudah tahu total jumlah produk dan bisa menghitung tepat berapa halaman yang diperlukan: pages = ceil(product_count / 250). Ini menghindari pola “satu request kosong di akhir”.
Langkah 4: Ambil dan Pilih Field yang Anda Butuhkan
Setelah semua produk ada dalam list dictionary Python, ambil hanya field yang kamu perlukan. Berikut contoh untuk pemantauan harga:
1def extract_product_data(products):
2 """Extract key fields from products, flattening variants."""
3 rows = []
4 for product in products:
5 for variant in product.get("variants", []):
6 rows.append({
7 "product_id": product["id"],
8 "title": product["title"],
9 "handle": product["handle"],
10 "vendor": product.get("vendor", ""),
11 "product_type": product.get("product_type", ""),
12 "tags": ", ".join(product.get("tags", [])),
13 "created_at": product.get("created_at", ""),
14 "variant_id": variant["id"],
15 "variant_title": variant.get("title", ""),
16 "sku": variant.get("sku", ""),
17 "price": variant.get("price", ""),
18 "compare_at_price": variant.get("compare_at_price", ""),
19 "available": variant.get("available", ""),
20 "image_url": product["images"][0]["src"] if product.get("images") else ""
21 })
22 return rows
Ini bikin satu baris per varian—format yang paling berguna untuk perbandingan harga, karena satu produk seperti "Classic Blue Jeans" bisa punya 12 varian (6 ukuran × 2 warna), masing-masing dengan harga dan status ketersediaan sendiri.
Ekspor Data Shopify Hasil Scrape ke CSV dan Excel dengan pandas
Tutorial scraping Shopify lain biasanya cuma buang JSON mentah ke file lalu selesai. Bagus buat developer. Tidak terlalu berguna buat analis ecommerce yang butuh spreadsheet sebelum Jumat sore.
Masalahnya: JSON Shopify itu bertingkat. Satu produk bisa punya belasan varian, masing-masing dengan harga, SKU, dan ketersediaan sendiri. Merapikannya menjadi baris dan kolom butuh sedikit bantuan pandas.
Ubah JSON Bertingkat Menjadi Tabel yang Rapi
Ada dua pendekatan, tergantung kebutuhanmu:
Opsi A: Satu baris per varian (terbaik untuk pemantauan harga dan stok)
1# Using the extract_product_data function from Step 4
2products = scrape_all_products("https://allbirds.com")
3rows = extract_product_data(products)
4df = pd.DataFrame(rows)
5print(f"DataFrame shape: {df.shape}")
6print(df.head())
Hasilnya adalah tabel datar di mana setiap baris mewakili satu kombinasi produk-varian. Toko dengan 500 produk dan rata-rata 4 varian per produk akan menghasilkan DataFrame sekitar 2.000 baris.
Opsi B: Satu baris ringkasan per produk (terbaik untuk overview katalog)
1def summarize_products(products):
2 """One row per product with min/max price across variants."""
3 rows = []
4 for product in products:
5 prices = [float(v["price"]) for v in product.get("variants", []) if v.get("price")]
6 rows.append({
7 "product_id": product["id"],
8 "title": product["title"],
9 "vendor": product.get("vendor", ""),
10 "product_type": product.get("product_type", ""),
11 "variant_count": len(product.get("variants", [])),
12 "min_price": min(prices) if prices else None,
13 "max_price": max(prices) if prices else None,
14 "any_available": any(v.get("available", False) for v in product.get("variants", [])),
15 "tags": ", ".join(product.get("tags", []))
16 })
17 return rows
Ekspor ke CSV, Excel, dan Google Sheets
1# CSV export (use utf-8-sig so Excel handles special characters)
2df.to_csv("shopify_products.csv", index=False, encoding="utf-8-sig")
3# Excel export (requires openpyxl)
4df.to_excel("shopify_products.xlsx", index=False, engine="openpyxl")
5print("Exported to shopify_products.csv and shopify_products.xlsx")
Untuk Google Sheets, kamu bisa pakai library gspread dengan service account, tapi jujur saja—untuk sebagian besar kasus, ekspor ke CSV lalu upload ke Google Drive jauh lebih cepat dan simpel.
Scraping Python yang Siap Produksi: Rate Limit, Retry, dan Anti-Blocking
Script dasar ini cukup untuk toko kecil. Tapi bagaimana kalau kamu scrape toko dengan 5.000+ produk, atau beberapa toko secara berurutan? Di situlah biasanya masalah mulai muncul.
Memahami Rate Limit dan Perilaku Blocking Shopify
Endpoint JSON publik Shopify tidak punya rate limit yang didokumentasikan secara formal (berbeda dengan model leaky bucket di Admin API), tapi dari pengujian empiris terlihat:
- Kecepatan aman: sekitar 2 request per detik per toko
- Batas lunak: sekitar 40 request per menit sebelum throttling aktif
- HTTP 429: "Too Many Requests"—respons standar rate limit
- HTTP 430: Kode khusus Shopify yang menandakan block di level keamanan (bukan sekadar rate limit)
- HTTP 403 atau redirect CAPTCHA: Beberapa toko dengan proteksi Cloudflare tambahan
Request dari infrastruktur cloud bersama (AWS Lambda, Google Cloud Run) sangat mudah memicu blokir karena rentang IP itu sering disalahgunakan.
Teknik untuk Scrape Shopify Secara Andal
Berikut progresi dari “jalan di laptop saya” menjadi “siap produksi”:
| Level | Teknik | Keandalan |
|---|---|---|
| Dasar | requests.get() + ?page= | Gampang gagal pada katalog besar, bisa diblokir |
| Menengah | requests.Session() + ?limit=250 + time.sleep(1) + retry saat 429 | Cocok untuk sebagian besar toko |
| Lanjutan | Async httpx + rotasi User-Agent + exponential backoff | Siap produksi, skala hingga 10K+ produk |
Tingkat menengah (direkomendasikan untuk kebanyakan pengguna):
1import requests
2from requests.adapters import HTTPAdapter
3from urllib3.util.retry import Retry
4def create_session():
5 """Create a requests session with automatic retry logic."""
6 session = requests.Session()
7 retries = Retry(
8 total=5,
9 backoff_factor=1, # sleep: 0.5s, 1s, 2s, 4s, 8s
10 status_forcelist=[429, 430, 500, 502, 503, 504],
11 respect_retry_after_header=True
12 )
13 session.mount("https://", HTTPAdapter(max_retries=retries))
14 session.headers.update({
15 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
16 })
17 return session
Konfigurasi Retry di atas menangani respons 429 secara otomatis dengan exponential backoff. backoff_factor=1 berarti urutan tidur adalah 0,5 detik → 1 detik → 2 detik → 4 detik → 8 detik di antara percobaan ulang. Pemakaian requests.Session() juga memberi connection pooling, jadi overhead saat melakukan banyak request ke domain yang sama jadi lebih kecil.
Rotasi User-Agent: Kalau kamu scrape beberapa toko, putar antara 3–5 string User-Agent browser yang realistis. Ini bukan soal menipu—ini soal tidak kelihatan seperti bot yang selalu mengirim header identik.
Script Python Lengkap untuk Scrape Shopify dengan Ekspor CSV
Berikut script lengkap yang bisa langsung kamu salin dan pakai. Isinya sekitar 75 baris kode nyata (plus komentar), dan saya sudah mengujinya pada Allbirds (1.420 produk), ColourPop (2.000+ produk), serta Zoologist Perfumes (katalog kecil).
1import requests
2import pandas as pd
3import time
4import random
5from requests.adapters import HTTPAdapter
6from urllib3.util.retry import Retry
7def create_session():
8 """Create a session with retry logic for rate limits."""
9 session = requests.Session()
10 retries = Retry(
11 total=5,
12 backoff_factor=1,
13 status_forcelist=[429, 430, 500, 502, 503, 504],
14 respect_retry_after_header=True
15 )
16 session.mount("https://", HTTPAdapter(max_retries=retries))
17 session.headers.update({
18 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
19 "AppleWebKit/537.36 (KHTML, like Gecko) "
20 "Chrome/125.0.0.0 Safari/537.36"
21 })
22 return session
23def scrape_shopify(store_url, delay=1.0):
24 """Scrape all products from a Shopify store via /products.json."""
25 session = create_session()
26 all_products = []
27 page = 1
28 base_url = f"{store_url.rstrip('/')}/products.json"
29 while True:
30 print(f" Page {page}...", end=" ")
31 resp = session.get(base_url, params={"limit": 250, "page": page}, timeout=30)
32 resp.raise_for_status()
33 products = resp.json().get("products", [])
34 if not products:
35 break
36 all_products.extend(products)
37 print(f"{len(products)} products (total: {len(all_products)})")
38 page += 1
39 time.sleep(delay + random.uniform(0, 0.5))
40 return all_products
41def flatten_to_variants(products):
42 """Flatten nested product JSON into one row per variant."""
43 rows = []
44 for p in products:
45 base = {
46 "product_id": p["id"],
47 "title": p["title"],
48 "handle": p["handle"],
49 "vendor": p.get("vendor", ""),
50 "product_type": p.get("product_type", ""),
51 "tags": ", ".join(p.get("tags", [])),
52 "created_at": p.get("created_at", ""),
53 "updated_at": p.get("updated_at", ""),
54 "image_url": p["images"][0]["src"] if p.get("images") else "",
55 }
56 for v in p.get("variants", []):
57 row = {**base}
58 row["variant_id"] = v["id"]
59 row["variant_title"] = v.get("title", "")
60 row["sku"] = v.get("sku", "")
61 row["price"] = v.get("price", "")
62 row["compare_at_price"] = v.get("compare_at_price", "")
63 row["available"] = v.get("available", "")
64 rows.append(row)
65 return rows
66if __name__ == "__main__":
67 STORE_URL = "https://allbirds.com" # Change this to your target store
68 OUTPUT_CSV = "shopify_products.csv"
69 OUTPUT_EXCEL = "shopify_products.xlsx"
70 print(f"Scraping {STORE_URL}...")
71 products = scrape_shopify(STORE_URL)
72 print(f"\nTotal products scraped: {len(products)}")
73 print("Flattening to variant-level rows...")
74 rows = flatten_to_variants(products)
75 df = pd.DataFrame(rows)
76 print(f"DataFrame: {df.shape[0]} rows x {df.shape[1]} columns")
77 df.to_csv(OUTPUT_CSV, index=False, encoding="utf-8-sig")
78 df.to_excel(OUTPUT_EXCEL, index=False, engine="openpyxl")
79 print(f"\nExported to {OUTPUT_CSV} and {OUTPUT_EXCEL}")
Jalankan dengan python scrape_shopify.py. Untuk Allbirds, proses ini memakan sekitar 45 detik dan menghasilkan CSV dengan ~5.000+ baris (satu baris per varian). Output terminalnya kira-kira seperti ini:
1Scraping https://allbirds.com...
2 Page 1... 250 products (total: 250)
3 Page 2... 250 products (total: 500)
4 ...
5 Page 6... 170 products (total: 1420)
6Total products scraped: 1420
7Flattening to variant-level rows...
8DataFrame: 5680 rows x 14 columns
9Exported to shopify_products.csv and shopify_products.xlsx
Lewati Python: Scrape Shopify dalam 2 Klik dengan Thunderbit (Alternatif Tanpa Kode)
Tidak semua orang mau install Python, memperbaiki error import, atau memelihara script scraping. Buat sales rep yang butuh harga kompetitor besok pagi, Python sering terasa terlalu ribet.
Karena itu kami membuat —AI web scraper yang berjalan sebagai ekstensi Chrome. Tanpa kode, tanpa API key, tanpa setup environment.
Cara Thunderbit Scrape Toko Shopify
Thunderbit punya Shopify Scraper template khusus yang sudah dikonfigurasi untuk halaman produk Shopify. Kamu tinggal pasang , buka toko Shopify, lalu klik "Scrape." Template ini otomatis mengekstrak nama produk, deskripsi, harga, detail varian, gambar, dan informasi vendor.
Untuk toko yang templatenya tidak cocok 100% (tema custom, layout yang tidak biasa), fitur AI Suggest Fields milik Thunderbit akan membaca halaman dan membuat nama kolom otomatis. Kamu bisa menyesuaikannya—ganti nama kolom, tambah field, atau kasih instruksi seperti "hanya ekstrak produk dengan compare_at_price terisi."
Beberapa fitur yang langsung sejalan dengan apa yang dilakukan script Python:
- Subpage scraping: Secara otomatis membuka setiap halaman detail produk dan memperkaya tabel dengan deskripsi lengkap, ulasan, atau detail varian—hal yang dilakukan script Python kita dengan iterasi halaman, tapi tanpa kode sama sekali.
- Automatic pagination: Menangani pagination klik-berdasarkan-halaman dan infinite scroll tanpa konfigurasi.
- Scheduled scraping: Buat tugas berkala (misalnya, "setiap Senin jam 9 pagi") untuk pemantauan harga berkelanjutan—tanpa cron job atau server.
- Ekspor gratis ke CSV, Excel, Google Sheets, Airtable, atau Notion di semua paket.
Script Python vs. Thunderbit: Perbandingan Jujur
| Faktor | Script Python | Thunderbit (Tanpa Kode) |
|---|---|---|
| Waktu setup | 15–60 menit (environment + code) | ~2 menit (install ekstensi Chrome) |
| Perlu coding | Ya (Python) | Tidak |
| Kustomisasi | Tidak terbatas | Field dari AI + prompt kustom |
| Penanganan pagination | Harus diprogram manual | Otomatis |
| Format ekspor | Harus dibuat sendiri (CSV/Excel) | CSV, Excel, Google Sheets, Airtable, Notion (gratis) |
| Run terjadwal | Cron job + hosting | Scheduler bawaan |
| Penanganan rate limit | Harus bikin retry/backoff sendiri | Ditangani otomatis |
| Paling cocok untuk | Developer, pipeline data skala besar | Pengguna bisnis, ekstraksi cepat, monitoring berulang |
Gunakan Python saat kamu butuh kontrol penuh atau ingin mengintegrasikannya ke pipeline data yang lebih besar. Gunakan Thunderbit saat kamu butuh data cepat dan tidak ingin memelihara kode. Untuk pembahasan lebih dalam tentang , kami sudah menulis panduan terpisah tentang topik itu.

Tips dan Praktik Terbaik Saat Scrape Toko Shopify
Hal-hal ini berlaku apa pun tool yang kamu pakai:
- Selalu gunakan
?limit=250supaya jumlah request minimum. Default 30 per halaman berarti 8x lebih banyak request untuk data yang sama. - Hormati server toko: kasih jeda 1–2 detik antar request. Menembaki server dengan request bertubi-tubi itu praktik buruk dan meningkatkan risiko diblokir.
- Cek
robots.txtdulu:robots.txtdefault Shopify TIDAK memblokir/products.json. Tapi beberapa toko menambahkan aturan khusus, jadi verifikasi sebelum scraping skala besar. - Simpan JSON mentah secara lokal dulu, baru diproses. Kalau logika parsing kamu berubah nanti, kamu nggak perlu scrape ulang. Cukup
json.dump(all_products, open("raw_data.json", "w"))sebelum merapikan data—ini sangat menghemat waktu. - Deduplikasi berdasarkan
product.id: Kadang edge case pagination bisa bikin produk dobel di batas halaman.df.drop_duplicates(subset=["product_id", "variant_id"])bisa beresin itu. - Ubah
priceke float sebelum menghitung apa pun. Shopify mengembalikan harga sebagai string ("185.00"), bukan angka. - Pantau perubahan endpoint: Walaupun
/products.jsonsudah stabil selama bertahun-tahun, secara teori Shopify bisa membatasinya. Kalau scraper tiba-tiba kena 404, cek toko secara manual dulu.
Untuk lebih lanjut tentang membangun scraper yang tangguh, lihat panduan kami tentang .
Pertimbangan Hukum dan Etika Saat Scrape Shopify
Bagian ini singkat, tapi penting.
Endpoint /products.json menyajikan data produk yang tersedia secara publik—informasi yang sama yang bisa dilihat siapa pun saat membuka toko. Terms of Service Shopify memang memuat bahasa tentang larangan memakai "automated means" untuk mengakses "the Services", tapi maksudnya adalah platform itu sendiri (dashboard admin, checkout), bukan data storefront publik. Sampai April 2026, belum ada gugatan hukum khusus Shopify terkait scraping.
Preseden hukum utama mendukung scraping data publik: kasus hiQ v. LinkedIn menetapkan bahwa scraping data yang bisa diakses publik tidak melanggar CFAA, dan Meta v. Bright Data (2024) memutuskan bahwa pembatasan TOS hanya berlaku saat pengguna login.
Praktik terbaik:
- Hanya scrape data produk yang memang publik
- Jangan scrape data pribadi atau data pelanggan
- Hormati
robots.txtdan rate limit - Patuhi GDPR/CCPA jika memproses data pribadi apa pun (data katalog produk bukan data pribadi)
- Identifikasi diri kamu dengan string User-Agent yang jelas
- Scraping toko Shopify milik sendiri via Admin API selalu aman
Untuk pembahasan lebih dalam, lihat artikel kami tentang .
Kesimpulan dan Poin Utama
Endpoint publik /products.json milik Shopify bikin ekstraksi data ecommerce jadi jauh lebih gampang. Alurnya: tambahkan /products.json → ambil dengan Python → lakukan pagination dengan ?limit=250&page= → rapikan dengan pandas → ekspor ke CSV atau Excel.
Apa yang dibahas panduan ini dan sering tidak dibahas panduan lain:
- Referensi field lengkap: tahu data apa saja yang tersedia (40+ field di produk, varian, dan gambar) sebelum nulis satu baris kode
- Endpoint tambahan:
/collections.jsondan/meta.jsonmemberi intelijen level kategori dan metadata toko yang biasanya tidak dibahas tutorial lain - Teknik siap produksi: Session reuse, exponential backoff, header User-Agent, dan
?limit=250untuk menangani rate limit dunia nyata - Ekspor CSV/Excel yang benar: Data varian yang sudah diratakan dengan pandas, bukan sekadar dump JSON mentah
- Alternatif tanpa kode: untuk pengguna yang lebih mementingkan kecepatan daripada fleksibilitas coding
Untuk pengambilan data Shopify satu kali atau berulang tanpa kode, coba —Shopify Scraper template menangani semuanya mulai dari pagination sampai ekspor. Untuk pipeline data kustom atau scraping skala besar di banyak toko, script Python di panduan ini memberi kamu kontrol penuh.
Kunjungi untuk video panduan, atau baca panduan kami tentang dan untuk teknik terkait.
FAQ
Bisa scrape semua toko Shopify dengan products.json?
Sebagian besar toko Shopify membuka endpoint ini secara default—dalam pengujian, sekitar 71% mengembalikan JSON valid. Beberapa toko dengan konfigurasi khusus atau lapisan keamanan tambahan (Cloudflare, setup headless) mungkin mengembalikan 404 atau memblokir request. Cek cepatnya: buka {store-url}/products.json di browser. Kalau kamu lihat JSON, berarti bisa.
Apakah legal scrape toko Shopify?
Data produk publik (harga, judul, gambar, deskripsi) umumnya bisa diakses, dan preseden hukum seperti hiQ v. LinkedIn mendukung scraping informasi yang tersedia untuk umum. Meski begitu, selalu periksa Terms of Service toko yang bersangkutan dan hukum di wilayahmu. Jangan scrape data pribadi atau data pelanggan, dan patuhi rate limit.
Berapa banyak produk yang bisa di-scrape dari toko Shopify?
Tidak ada batas keras untuk totalnya. Pagination dengan ?limit=250&page= memungkinkan kamu mengambil seluruh katalog. Untuk toko yang sangat besar (25.000+ produk), gunakan session reuse dan jeda supaya tidak kena rate limit. Endpoint /meta.json bisa memberi tahu jumlah produk secara pasti sejak awal, jadi kamu tahu kira-kira berapa halaman yang akan dihadapi.
Apa bedanya products.json dengan Shopify Admin API?
/products.json adalah endpoint publik—tanpa autentikasi, data produk read-only, bisa diakses siapa saja. Admin API memerlukan token akses pemilik toko dan menyediakan pesanan, jumlah inventori, data pelanggan, serta akses tulis. Kalau kamu butuh data penjualan atau jumlah stok yang sebenarnya, kamu harus punya akses Admin API (artinya kamu pemilik toko atau dapat izin dari mereka).
Bisa scrape Shopify tanpa Python?
Tentu bisa. Tool seperti memungkinkan kamu scrape toko Shopify lewat ekstensi Chrome tanpa coding. Pagination ditangani otomatis dan hasilnya bisa langsung diekspor ke CSV, Excel, Google Sheets, Airtable, atau Notion. Bagi developer yang lebih suka bahasa lain, endpoint /products.json yang sama juga bisa dipakai dengan JavaScript, Ruby, Go—apa pun bahasa yang bisa mengirim HTTP request dan mem-parsing JSON.
Pelajari Lebih Lanjut