Pazar Araştırmanızı Otomatikleştirin: Python ile Shopify Verisi Çekin

Son güncelleme: April 16, 2026

Shopify’ın /products.json endpoint’i, e-ticaret verileri dünyasının en iyi saklanan sırlarından biri sayılır. Bir Shopify mağazasının URL’sinin sonuna bunu eklediğinizde, size yapılandırılmış bir JSON yanıtı döner — API anahtarı yok, kimlik doğrulama yok, iç içe geçmiş HTML’i kazıma derdi yok.

Ben Thunderbit Official Website ekibinde çalışıyorum; bu yüzden insanların web’den veri çekme yöntemleri üzerine epey kafa yoruyorum. Shopify scraping konusu da sürekli gündeme geliyor: rakip fiyatlarını takip eden satış ekipleri, ürün kataloglarını kıyaslayan e-ticaret operasyonları, yeni tedarikçiler arayan satın alma ekipleri… Shopify’da bulunuyor ve platform ABD e-ticaret pazarının yaklaşık sahip. Bu da çekilebilir ürün verisinin ne kadar büyük bir hacme ulaştığını gösteriyor.

Bu rehber, sürecin tamamını kapsıyor: endpoint’in ne döndürdüğü, binlerce üründe nasıl sayfalama yapılacağı, rate limit’e takılmadan nasıl ilerleyeceğiniz ve Shopify’ın iç içe JSON yapısını pandas kullanarak temiz bir CSV ya da Excel dosyasına nasıl dönüştüreceğiniz. Ayrıca kimsenin çok konuşmadığı endpoint’leri de (/collections.json, /meta.json) ele alacak ve Python kullanmak istemeyenler için kodsuz bir alternatif göstereceğim.

Shopify’ın /products.json Endpoint’i Nedir ve Scraping’i Neden Bu Kadar Kolaylaştırır?

Her Shopify mağazasının {store-url}/products.json adresinde herkese açık bir endpoint’i vardır ve bu endpoint yapılandırılmış ürün verisi döndürür. API anahtarı yok. OAuth yok. Hiçbir tür kimlik doğrulama yok. Mağaza URL’sinin sonuna sadece /products.json eklemeniz yeterli; katalogdaki tüm ürünlerin JSON dizisini alırsınız.

Bunu şimdi kendiniz deneyebilirsiniz: tarayıcınızda veya adresini açın. Ürün başlıkları, fiyatlar, varyantlar, görseller, etiketler ve daha fazlasını içeren temiz, düzenli bir JSON yapısı göreceksiniz.

Bunu alternatif yöntemle karşılaştırın: Shopify’ın HTML temalarını ayrıştırmak. Bu yapılar oldukça iç içedir, mağazalar arasında tutarsızdır ve satıcı temayı güncellediğinde değişir. Karşılaşacağınız yapı şu olur:

HTML yaklaşımı (can sıkıcı):

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>

JSON yaklaşımı (temiz):

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}

Tutarlılık, güvenilirlik ve ayrıştırma kolaylığı açısından JSON açık ara önde. Endpoint ayrıca iki temel sorgu parametresini destekler: ?limit= (sayfa başına en fazla 250 ürün, varsayılan 30) ve sayfalama için ?page=. Bunları aşağıdaki kodda yoğun şekilde kullanacağız.

Önemli ayrım şu: Bu bir herkese açık storefront endpoint’i, değil. Admin API, mağaza sahibinin erişim token’ını gerektirir ve sipariş verisi, stok seviyeleri ve müşteri bilgileri sunar. Halkın erişebildiği /products.json endpoint’i ise salt okunur ürün verisi verir ve herkes tarafından erişilebilir. Bu farkı ileride detaylıca ele alacağım; çünkü forumlarda bu konuda ciddi bir kafa karışıklığı var.

Bir uyarı: Her Shopify mağazası bu endpoint’i açmaz. Testlerimde mağazaların yaklaşık yüzde 71’i geçerli JSON döndürdü (allbirds.com, gymshark.com, colourpop.com, kyliecosmetics.com çalışıyor); bazı özel yapılandırmalar ise 404 döndürüyor (hiutdenim.co.uk, bombas.com). Hızlı kontrol basit: {store-url}/products.json adresini tarayıcıda açın ve ne döndüğüne bakın.

Neden Python ile Shopify Verisi Çekmelisiniz? Başlıca İş Kullanım Senaryoları

Neden uğraşasınız? Çünkü geri dönüşü var. artık rekabet istihbaratı için otomatik fiyat çekimi kullanıyor; bu oran 2020’de yalnızca yüzde 34’tü. Araştırmalar, gösteriyor. Yani bu veriler gerçek para değerinde.

En sık gördüğüm kullanım alanları şunlar:

Kullanım SenaryosuKimler İçin FaydalıElde Edeceğiniz Veri
Rakip fiyat takibiE-ticaret operasyon ekipleriRakip kataloglarında fiyat değişimleri, indirimler ve karşılaştırma fiyatlarını izleme
Ürün araştırması ve tedarikSatın alma / merchandising ekipleriÜrün özelliklerini, varyantları, materyalleri ve stok durumunu karşılaştırma
Lead oluşturmaSatış ekipleriMağaza kataloglarından satıcı adlarını, marka verilerini ve iletişim bilgilerini çekme
Pazar ve kategori analiziPazarlama ekipleriÜrün karmasını, etiketleri, koleksiyon yapısını ve konumlandırmayı anlama
Stok ve erişilebilirlik takibiTedarik zinciri ekipleriVaryant bazında stok durumunu (available: true/false) zaman içinde izleme
Yeni ürün tespitiÜrün ekipleriRakiplerde yeni lansmanları görmek için created_at zaman damgalarını takip etme

Bu iş için Python doğal bir seçim. ana dil olarak Python kullanıyor. requests ile HTTP istekleri, pandas ile veri dönüştürme, httpx ile async işlemler sayesinde “elimde bir URL var” noktasından “elimde bir tablo var” noktasına 80 satırdan kısa kodla geçmek mümkün.

Tam products.json Alan Rehberi: Tüm Alanlar Tek Tek Açıklanıyor

Diğer rehberlerin çoğu size sadece title, id ve handle alanlarını gösterip devam eder. Oysa Shopify’ın JSON yanıtı, ürünler, varyantlar, görseller ve seçenekler genelinde 40’tan fazla alan içerir. Scraping kodunu yazmadan önce hangi alanların mevcut olduğunu bilmek, sonradan yeniden scraping yapma ihtiyacını azaltır.

Bu referansı 16 Nisan 2026 tarihinde alınmış canlı /products.json yanıtlarından derledim. Endpoint’i sunan tüm mağazalarda yapı tutarlıdır.

Ürün Seviyesi Alanlar

AlanVeri TürüÖrnek Değerİş Kullanımı
idTam sayı123456789Tekil ürün kimliği; yinelenenleri ayıklamak için
titleMetin"Classic Blue Jeans"Kataloglar ve karşılaştırmalar için ürün adı
handleMetin"classic-blue-jeans"URL slug’ı — ürün sayfası bağlantısını {store}/products/{handle} şeklinde oluşturabilirsiniz
body_htmlMetin (HTML) veya null

Our best-selling...

İçerik analizi ve SEO araştırması için ürün açıklaması
vendorMetin"Hiut Denim"Lead oluşturma veya tedarik için marka / satıcı adı
product_typeMetin"Jeans"Pazar analizi için kategori sınıflandırması
created_atISO DateTime"2024-01-15T10:30:00-05:00"Ürünlerin ne zaman eklendiğini izleme (yeni lansman tespiti)
updated_atISO DateTime"2025-03-01T08:00:00-05:00"Katalogda yakın zamanda yapılan değişiklikleri tespit etme
published_atISO DateTime"2024-01-16T00:00:00-05:00"Ürünlerin mağazada ne zaman yayına alındığını bilme
tagsMetin dizisi["organic", "women", "straight-leg"]SEO, sınıflandırma ve trend analizi için etiket / anahtar kelime inceleme
variantsNesne dizisi(aşağıdaki varyant alanlarına bakın)Her varyant için fiyat, SKU, stok durumu
imagesNesne dizisi(aşağıdaki görsel alanlarına bakın)Katalog ve görsel analiz için ürün görsel URL’leri
optionsNesne dizisi[{"name": "Size", "values": ["S","M","L"]}]Ürün konfigürasyonunu anlama (beden, renk, materyal)

Varyant Seviyesi Alanlar (her ürünün altında yer alır)

AlanVeri TürüÖrnekKullanım Alanı
idTam sayı987654321Tekil varyant kimliği
titleMetin"32 / Blue"Varyant gösterim adı
skuMetin"HD-BLU-32"Envanter sistemleri için SKU eşleştirme
priceMetin"185.00"Fiyat takibi (not: sayı değil, metin olarak gelir; matematik için float’a dönüştürün)
compare_at_priceMetin veya null"200.00"Eski fiyat — indirim takibinde kritik
availableBooletrueStok erişilebilirliği (kamuya açık tek stok göstergesi)
weightOndalık sayı1.2Kargo / lojistik analizi
option1, option2, option3Metin"32", "Blue", nullTekil seçenek değerleri
created_at, updated_atISO DateTimeVaryant düzeyinde değişim takibi

Görsel Seviyesi Alanlar

AlanVeri TürüÖrnekKullanım Alanı
idTam sayı111222333Tekil görsel kimliği
srcMetin (URL)"https://cdn.shopify.com/..."Doğrudan görsel indirme bağlantısı
altMetin veya null"Front view of jeans"Erişilebilirlik analizi için alternatif metin
positionTam sayı1Görsel sıralaması
width, heightTam sayı2048, 2048Görsel boyutları

Genel Endpoint’te Bulunmayanlar

Kritik bir nokta: inventory_quantity, herkese açık /products.json yanıtlarında yer almaz. Bu alan, güvenlik nedenleriyle Aralık 2017’de herkese açık JSON endpoint’lerinden kaldırıldı. Kamuya açık olarak alabileceğiniz tek stok göstergesi, her varyanttaki boole available alanıdır (true veya false). Gerçek stok miktarını görmek için mağaza sahibinin kimlik bilgileriyle erişilen doğrulanmış Admin API gerekir.

Scraping kodunu yazmadan önce bu tabloya bakın ve kullanım senaryonuz için hangi alanların önemli olduğuna karar verin. Fiyat takibi yapıyorsanız variants[].price, variants[].compare_at_price ve variants[].available alanlarına ihtiyacınız vardır. Lead oluşturma yapıyorsanız vendor, product_type ve tags üzerine odaklanın. Buna göre filtre uygulayın — CSV’niz çok daha temiz olur.

products.json Ötesi: Collections, Meta ve Diğer Shopify Endpoint’leri

Rakip rehberlerin hiçbiri bu endpoint’lerden bahsetmez. Oysa ciddi rekabet istihbaratı çalışmaları için bunlar çok önemlidir.

/collections.json — Mağazadaki Tüm Kategoriler

Mağazadaki tüm koleksiyonları (kategorileri) başlıkları, handle’ları, açıklamaları ve ürün sayılarıyla birlikte döndürür. Bunu zoologistperfumes.com, allbirds.com ve gymshark.com üzerinde doğruladım — hepsi geçerli JSON döndürüyor.

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}

Rakibin katalog yapısını nasıl organize ettiğini anlamak mı istiyorsunuz? Aradığınız endpoint bu.

/collections/{handle}/products.json — Kategori Bazında Ürünler

Belirli bir koleksiyona göre filtrelenmiş ürünleri döndürür. /products.json ile aynı JSON yapısını kullanır, ancak tek bir kategoriyle sınırlıdır. Bu, kategori bazlı scraping için kritik önemdedir — örneğin bir rakibin yalnızca “Sale” ya da “New Arrivals” koleksiyonunu izlemek isteyebilirsiniz.

/meta.json — Mağaza Düzeyi Meta Veriler

Mağaza adı, açıklama, para birimi, ülke ve en güzeli published_products_count değerini döndürür. Bu sayı sayesinde kaç sayfa dolaşmanız gerektiğini önceden tam olarak hesaplayabilirsiniz: ceil(published_products_count / 250). Artık boş yanıt gelene kadar sayfa numarasını körlemesine artırmanıza gerek yok.

Hangi Endpoint’i Kullanmalısınız?

İhtiyacınız OlanEndpointKimlik Doğrulama Gerekli mi?
Tüm ürünler (herkese açık)/products.jsonHayır
Belirli kategorideki ürünler/collections/{handle}/products.jsonHayır
Mağaza meta verisi + ürün sayısı/meta.jsonHayır
Tüm koleksiyonlar (kategoriler)/collections.jsonHayır
Sipariş / satış verisi (yalnızca kendi mağazanız)Admin API /orders.jsonEvet (API anahtarı)
Stok miktarları (yalnızca kendi mağazanız)Admin API /inventory_levels.jsonEvet

Forumlarda sık sorulan soru — “Rakibin kaç adet sattığını çekebilir miyim?” — kısa cevabı şudur: hayır. Herkese açık endpoint’lerden değil. Satış verisi ve stok miktarları, kimlik doğrulamalı Admin API gerektirir; yani mağaza sahibinin erişimine ihtiyacınız vardır. Herkese açık endpoint’ler yalnızca ürün katalog verisi sağlar.

shopify-data-access-methods.webp

Python ile Shopify Verisi Nasıl Çekilir: Adım Adım Kurulum

  • Zorluk: Başlangıç seviyesi
  • Süre: Yaklaşık 15 dakika (kurulum + ilk çekim)
  • Gerekenler: Python 3.11+, pip, bir terminal ve çekmek istediğiniz Shopify mağaza URL’si

1. Adım: Python ve Gerekli Kütüphaneleri Kurun

Python 3.11 veya daha yeni bir sürümün kurulu olduğundan emin olun (pandas 3.0.x bunu gerektirir). Ardından ihtiyacımız olan iki kütüphaneyi yükleyin:

1pip install requests pandas

Excel’e aktarma için ayrıca şunu da kurmanız gerekir:

1pip install openpyxl

Script’in en üstüne şu import’ları ekleyin:

1import requests
2import pandas as pd
3import time
4import random
5import json

Script’i çalıştırdığınızda import hatası görmemeniz gerekir. Eğer pandas sürüm hatası verirse Python’u 3.12’ye yükseltin.

2. Adım: /products.json Endpoint’inden Ürün Verisini Çekin

Aşağıdaki temel fonksiyon, bir mağaza URL’si alır, endpoint’e istek gönderir ve ayrıştırılmış JSON’u döndürür:

1def fetch_products_page(store_url, page=1, limit=250):
2    """Bir Shopify mağazasından tek bir ürün sayfası çeker."""
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", [])

Önemli noktalar:

  • limit=250 Shopify’ın sayfa başına izin verdiği en yüksek değerdir. Varsayılan 30’dur; bunu açıkça belirlemek toplam istek sayınızı 8 kata kadar azaltır.
  • User-Agent başlığı: Her zaman gerçekçi bir değer kullanın. User-Agent olmadan gönderilen isteklerin Shopify’ın bot karşıtı sistemlerini tetikleme olasılığı daha yüksektir.
  • timeout=30: Tek bir isteğin sonsuza kadar takılı kalmasına izin vermeyin.

Bunu bilinen bir mağaza ile test edin:

1products = fetch_products_page("https://allbirds.com")
2print(f"{len(products)} ürün çekildi")
3print(f"İlk ürün: {products[0]['title']}")

Şuna benzer bir çıktı görmelisiniz: 250 ürün çekildi ve ardından ilk ürün başlığı.

3. Adım: Tüm Ürünleri Çekmek İçin Sayfalama Yapın

Tek bir istek en fazla 250 ürün döndürür. Çoğu mağazada bunun çok üzerinde ürün vardır (Allbirds’te 1.420+ ürün var). Boş bir yanıt alana kadar sayfalar arasında döngü kurmanız gerekir.

1def scrape_all_products(store_url, delay=1.0):
2    """Sayfalama yaparak bir Shopify mağazasındaki tüm ürünleri çeker."""
3    all_products = []
4    page = 1
5    while True:
6        print(f"Sayfa {page} çekiliyor...")
7        products = fetch_products_page(store_url, page=page, limit=250)
8        if not products:
9            print(f"Başka ürün yok. Toplam: {len(all_products)}")
10            break
11        all_products.extend(products)
12        print(f"  {len(products)} ürün alındı (şu ana kadar toplam: {len(all_products)})")
13        page += 1
14        # Nazik olun: istekler arasında bekleyin
15        time.sleep(delay + random.uniform(0, 0.5))
16    return all_products

products boş dönünce sonuna gelmişsiniz demektir.

time.sleep() ile birlikte kullanılan rastgele gecikme, sizi Shopify’ın gayriresmî rate limit sınırının altında tutar (yaklaşık saniyede 2 istek).

İpucu: Önce /meta.json çektiyseniz, toplam ürün sayısını zaten bilirsiniz ve tam olarak kaç sayfaya ihtiyacınız olduğunu hesaplayabilirsiniz: pages = ceil(product_count / 250). Böylece en sonda gelen “fazladan bir boş istek” durumundan kurtulursunuz.

4. Adım: İhtiyacınız Olan Alanları Ayrıştırın ve Seçin

Artık elinizde Python listesi içinde sözlükler halinde ürünler var; şimdi sadece ilgilendiğiniz alanları çekin. Aşağıda fiyat takibi için en yaygın alanları alan bir örnek var:

1def extract_product_data(products):
2    """Ürünlerden temel alanları çıkarır ve varyantları düzleştirir."""
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

Bu yapı, her varyant için bir satır oluşturur. Fiyat karşılaştırması için en kullanışlı form budur; çünkü “Classic Blue Jeans” gibi tek bir ürünün 12 varyantı olabilir (6 beden × 2 renk) ve her birinin kendi fiyatı ile stok durumu bulunur.

Çekilen Shopify Verisini pandas ile CSV ve Excel’e Aktarma

Diğer Shopify scraping rehberlerinin çoğu ham JSON’u bir dosyaya kaydedip işin bittiğini söyler. Geliştiriciler için yeterli olabilir. Ama cuma gününe kadar bir tabloya ihtiyacı olan e-ticaret analisti için hiçbir işe yaramaz.

Sorun şu: Shopify’ın JSON yapısı iç içedir. Tek bir ürün, her biri kendi fiyatına, SKU’suna ve stok durumuna sahip onlarca varyant içerebilir. Bunu satır ve sütunlara dönüştürmek biraz pandas işi gerektirir.

İç İçe JSON’u Temiz Bir Tabloya Dönüştürün

Kullanım senaryonuza göre iki yaklaşım var:

Seçenek A: Varyant başına bir satır (fiyat takibi ve stok izlemesi için en iyi yöntem)

1# 4. adımda tanımlanan extract_product_data fonksiyonunu kullanarak
2products = scrape_all_products("https://allbirds.com")
3rows = extract_product_data(products)
4df = pd.DataFrame(rows)
5print(f"DataFrame boyutu: {df.shape}")
6print(df.head())

Bu size her satırın benzersiz bir ürün-varyant kombinasyonu olduğu düz bir tablo verir. 500 ürünü olan ve ürün başına ortalama 4 varyant barındıran bir mağaza yaklaşık 2.000 satırlık bir DataFrame üretir.

Seçenek B: Ürün özeti başına bir satır (katalog genel görünümü için en iyi yöntem)

1def summarize_products(products):
2    """Varyantlar arasında min/maks fiyatla ürün başına bir satır oluşturur."""
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

CSV, Excel ve Google Sheets’e Aktarın

1# CSV dışa aktarma (Excel’in özel karakterleri doğru işlemesi için utf-8-sig kullanın)
2df.to_csv("shopify_products.csv", index=False, encoding="utf-8-sig")
3# Excel dışa aktarma (openpyxl gerekir)
4df.to_excel("shopify_products.xlsx", index=False, engine="openpyxl")
5print("shopify_products.csv ve shopify_products.xlsx olarak dışa aktarıldı")

Google Sheets için gspread kütüphanesini bir service account ile kullanabilirsiniz; ama dürüst olmak gerekirse çoğu kullanım senaryosunda CSV dışa aktarıp Google Drive’a yüklemek daha hızlı ve basittir.

Üretim Ortamına Hazır Python Scraping: Rate Limit, Retry ve Engelleme Önleme

Temel script küçük mağazalar için gayet yeterli. Peki 5.000+ ürünü olan bir mağazayı çekmek ya da arka arkaya birden fazla mağazada çalıştırmak? İşte sorunlar burada başlıyor.

Shopify’ın Rate Limit ve Engelleme Davranışını Anlamak

Shopify’ın herkese açık JSON endpoint’leri, Admin API’deki leak bucket modeli gibi resmi olarak belgelenmiş rate limit’lere sahip değil; ancak pratik testler şunları gösteriyor:

  • Güvenli hız: mağaza başına saniyede yaklaşık 2 istek
  • Yumuşak üst sınır: throttling başlamadan önce dakikada yaklaşık 40 istek
  • HTTP 429: “Too Many Requests” — standart rate limit yanıtı
  • HTTP 430: Shopify’a özgü bir kod; yalnızca rate limit değil, güvenlik seviyesi blok anlamına gelebilir
  • HTTP 403 veya CAPTCHA yönlendirmesi: Bazı mağazalarda ek Cloudflare koruması

AWS Lambda veya Google Cloud Run gibi paylaşımlı bulut altyapılarından gelen istekler, bu IP aralıklarının kötüye kullanım oranı yüksek olduğu için daha kolay engellenebilir.

Shopify Verisini Güvenilir Şekilde Çekme Teknikleri

Aşağıda “kendi bilgisayarımda çalışıyor” seviyesinden “üretimde sorunsuz çalışıyor” seviyesine doğru ilerleyen yaklaşım var:

SeviyeTeknikGüvenilirlik
Temelrequests.get() + ?page=Büyük kataloglarda bozulur, engellenebilir
Ortarequests.Session() + ?limit=250 + time.sleep(1) + 429’da retryÇoğu mağazada çalışır
İleriDöngüsel httpx + değişken User-Agent + üssel geri çekilme (exponential backoff)Üretim kalitesinde, 10K+ ürüne ölçeklenebilir

Orta seviye yaklaşım (çoğu kullanıcı için önerilir):

1import requests
2from requests.adapters import HTTPAdapter
3from urllib3.util.retry import Retry
4def create_session():
5    """Rate limit’ler için otomatik retry mantığına sahip bir requests oturumu oluşturur."""
6    session = requests.Session()
7    retries = Retry(
8        total=5,
9        backoff_factor=1,  # uyku süresi: 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

Retry ayarı, 429 yanıtlarını üssel geri çekilme ile otomatik olarak yönetir. backoff_factor=1 olması, yeniden denemeler arasında bekleme süresinin 0.5s → 1s → 2s → 4s → 8s şeklinde ilerlediği anlamına gelir. requests.Session() kullanımı ise bağlantı havuzlaması sağlar; bu da aynı domaine birden çok istek atarken ek yükü azaltır.

User-Agent rotasyonu: Birden fazla mağaza çekiyorsanız, 3–5 gerçekçi tarayıcı User-Agent dizisi arasında dönüş yapın. Bu, kandırma meselesi değil; her istekte aynı başlıkları gönderen bir bot gibi görünmemekle ilgilidir.

CSV Dışa Aktaran Tam Çalışan Python Script’i ile Shopify Verisi Çekin

Aşağıda, yukarıdakilerin hepsini bir araya getiren, doğrudan kopyalayıp çalıştırabileceğiniz tam script var. Gerçek kod yaklaşık 75 satırdan oluşuyor (yorumlar hariç) ve Allbirds (1.420 ürün), ColourPop (2.000+ ürün) ve Zoologist Perfumes (küçük katalog) üzerinde test edildi.

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    """Rate limit’ler için retry mantığına sahip bir oturum oluşturur."""
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    """Bir Shopify mağazasındaki tüm ürünleri /products.json üzerinden çeker."""
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"  Sayfa {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)} ürün (toplam: {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    """İç içe ürün JSON’unu varyant başına bir satıra dönüştürür."""
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"  # Hedef mağaza ile değiştirin
68    OUTPUT_CSV = "shopify_products.csv"
69    OUTPUT_EXCEL = "shopify_products.xlsx"
70    print(f"{STORE_URL} çekiliyor...")
71    products = scrape_shopify(STORE_URL)
72    print(f"\nToplam çekilen ürün sayısı: {len(products)}")
73    print("Varyant seviyesinde satırlara dönüştürülüyor...")
74    rows = flatten_to_variants(products)
75    df = pd.DataFrame(rows)
76    print(f"DataFrame: {df.shape[0]} satır x {df.shape[1]} sütun")
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"\n{OUTPUT_CSV} ve {OUTPUT_EXCEL} olarak dışa aktarıldı")

python scrape_shopify.py komutuyla çalıştırın. Allbirds için bu işlem yaklaşık 45 saniye sürer ve yaklaşık 5.000+ satırlık bir CSV üretir (varyant başına bir satır). Terminal çıktısı kabaca şöyle görünür:

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

Python Kullanmak İstemiyorsanız: Thunderbit ile 2 Tıkta Shopify Verisi Çekin (Kodsuz Alternatif)

Herkes Python kurmak, import hatalarını çözmek ya da scraping script’i bakımında zaman harcamak istemez. Yarın sabah rakip fiyatlarına ihtiyaç duyan bir satış temsilcisi için Python fazla kaçabilir.

İşte bu yüzden ’i geliştirdik — Chrome uzantısı olarak çalışan bir AI web scraper. Kod yok, API anahtarı yok, ortam kurulumu yok.

Thunderbit Shopify Mağazalarını Nasıl Çeker?

Thunderbit’te Shopify ürün sayfaları için önceden yapılandırılmış özel bir Shopify Scraper şablonu bulunur. sayfasından uzantıyı kurar, bir Shopify mağazasına gider ve “Scrape” düğmesine basarsınız. Şablon, ürün adlarını, açıklamaları, fiyatları, varyant detaylarını, görselleri ve satıcı bilgilerini otomatik olarak çeker.

Şablonun tam uyum sağlamadığı mağazalarda (özel temalar, sıra dışı düzenler gibi), Thunderbit’in AI Suggest Fields özelliği sayfayı okur ve sütun adlarını otomatik oluşturur. Bunları özelleştirebilirsiniz — sütunları yeniden adlandırabilir, alan ekleyebilir, “yalnızca compare_at_price değeri olan ürünleri çek” gibi talimatlar verebilirsiniz.

Python script’inin yaptığı işlemlerle doğrudan eşleşen bazı özellikler:

  • Alt sayfa scraping: Her ürün detay sayfasını otomatik ziyaret eder ve tabloyu tam açıklamalar, yorumlar veya varyant detaylarıyla zenginleştirir — bizim Python script’inin sayfalar arasında döngü kurarak yaptığı şeyin kodsuz hali.
  • Otomatik sayfalama: Tıklamalı sayfalama ve sonsuz kaydırmayı herhangi bir ayar gerektirmeden yönetir.
  • Zamanlanmış scraping: Sürekli fiyat takibi için tekrar eden işler kurabilirsiniz (ör. “her Pazartesi saat 09:00’da”) — cron job ya da sunucu gerekmez.
  • Tüm planlarda ücretsiz dışa aktarma: CSV, Excel, Google Sheets, Airtable veya Notion’a ücretsiz aktarım.

Python Script’i vs. Thunderbit: Dürüst Karşılaştırma

KriterPython ScriptThunderbit (Kodsuz)
Kurulum süresi15–60 dk (ortam + kod)Yaklaşık 2 dk (Chrome uzantısı kurulumu)
Kod gerekli mi?Evet (Python)Hayır
ÖzelleştirmeSınırsızAI önerili alanlar + özel prompt’lar
Sayfalama yönetimiElle kodlanmalıOtomatik
Dışa aktarma formatlarıKendi kodlamanız gerekir (CSV/Excel)CSV, Excel, Google Sheets, Airtable, Notion (ücretsiz)
Zamanlanmış çalıştırmaCron job + barındırmaDahili zamanlayıcı
Rate limit yönetimiRetry/backoff kodlamanız gerekirOtomatik yönetilir
En uygun kullanımGeliştiriciler, büyük ölçekli veri boru hatlarıİş kullanıcıları, hızlı çekimler, düzenli izleme

Tam kontrol ve geniş bir veri hattına entegrasyon gerektiğinde Python’u kullanın. Veriye hızlı ulaşmak ve kod bakımıyla uğraşmamak istediğinizde Thunderbit’i tercih edin. hakkında daha ayrıntılı bir bakış için, bu konuya özel bir rehber de hazırladık.

python-vs-thunderbit-comparison.webp

Shopify Mağazalarını Çekerken İpuçları ve En İyi Uygulamalar

Bu öneriler, hangi aracı kullandığınızdan bağımsız olarak geçerlidir:

  • Her zaman ?limit=250 kullanın: Toplam istek sayısını azaltır. Varsayılan 30 sayfa başına ürün demek, aynı veri için 8 kat daha fazla istek atmanız anlamına gelir.
  • Mağazaya saygılı davranın: İstekler arasına 1–2 saniye gecikme koyun. Sunucuyu art arda isteklerle bombardımana tutmak kötü pratiktir ve engellenme riskini artırır.
  • Önce robots.txt kontrol edin: Shopify’ın varsayılan robots.txt dosyası /products.json için engel koymaz. Ancak bazı mağazalar özel kurallar ekleyebilir; bu yüzden büyük ölçekli scraping’den önce kontrol edin.
  • Ham JSON’u önce yerelde saklayın, sonra işlem yapın. Ayrıştırma mantığınız ileride değişirse yeniden scraping yapmak zorunda kalmazsınız. Düzleştirmeden önce basit bir json.dump(all_products, open("raw_data.json", "w")) işlemi çok işinizi kolaylaştırır.
  • product.id ile benzersizleştirin: Sayfalama sınırlarında bazen aynı ürün iki kez dönebilir. df.drop_duplicates(subset=["product_id", "variant_id"]) bunu hızlıca temizler.
  • Fiyatı matematik yapmadan önce float’a çevirin: Shopify fiyatları sayı değil, metin olarak döndürür ("185.00" gibi).
  • Endpoint değişikliklerini izleyin: /products.json yıllardır stabil olsa da Shopify teorik olarak erişimi kısıtlayabilir. Scraper bir anda 404 verirse önce mağazayı manuel kontrol edin.

Daha sağlam scraper’lar kurmak için rehberimize göz atın.

Shopify Verisi Çekerken Yasal ve Etik Hususlar

Kısa bir bölüm ama önemli.

/products.json endpoint’i herkese açık ürün verisi sunar — mağazayı gezen herhangi bir ziyaretçinin görebileceği bilgilerle aynıdır. Shopify’ın Kullanım Şartları, “hizmetlere” erişmek için “otomatik yollar” kullanılmamasına dair ifadeler içerir; ancak bu ifade platformun kendisini (yönetim paneli, ödeme süreci) hedef alır, herkese açık storefront verisini değil. Nisan 2026 itibarıyla Shopify’a özgü bir scraping davası açılmış değildir.

Kamuya açık veriyi çekmeyi destekleyen önemli yasal emsaller vardır: hiQ v. LinkedIn davası, herkese açık verinin çekilmesinin CFAA’yı ihlal etmediğini ortaya koydu; Meta v. Bright Data (2024) ise kullanım şartı kısıtlarının yalnızca kullanıcı giriş yapmışsa geçerli olduğunu hükme bağladı.

En iyi uygulamalar:

  • Yalnızca herkese açık ürün verisini çekin
  • Kişisel veya müşteri verisi çekmeyin
  • robots.txt ve rate limit’lere uyun
  • Kişisel veri işliyorsanız GDPR/CCPA’ya uyun (ürün katalog verisi kişisel değildir)
  • Kendinizi açık bir User-Agent dizisiyle tanıtın
  • Kendi Shopify mağazanızı Admin API ile çekmek her zaman uygundur

Daha derin bir inceleme için yazımıza bakın.

Sonuç ve Öne Çıkan Noktalar

Shopify’ın herkese açık /products.json endpoint’i, e-ticaret verisi çıkarmayı mümkün olduğunca kolay hale getiriyor. İş akışı şu: /products.json ekle → Python ile çek → ?limit=250&page= ile sayfala → pandas ile düzleştir → CSV veya Excel’e aktar.

Bu rehberin diğerlerinde olmayan katkıları:

  • Tam alan referansı: Tek bir satır kod yazmadan önce hangi verilerin mevcut olduğunu tam olarak öğrenin (ürünler, varyantlar ve görseller genelinde 40+ alan)
  • Ek endpoint’ler: /collections.json ve /meta.json, kategori düzeyinde içgörü ve mağaza meta verisi sağlar; bunları çoğu rehber ele almaz
  • Üretime hazır teknikler: Gerçek dünya rate limit’lerini yönetmek için session reuse, exponential backoff, User-Agent başlıkları ve ?limit=250
  • Doğru CSV/Excel dışa aktarma: Ham JSON dökümü değil, pandas ile düzleştirilmiş varyant seviyesinde veri
  • Kodsuz alternatif: Kod esnekliğinden çok hıza önem veren kullanıcılar için

Kod yazmadan tek seferlik ya da düzenli Shopify veri çekimleri için sayfasını deneyin — Shopify Scraper şablonu sayfalama ve dışa aktarma dahil her şeyi halleder. Çok mağazalı özel veri boru hatları veya ölçekli scraping için bu rehberdeki Python script’i tam kontrol sunar.

Video anlatımlar için kanalına göz atın veya ilgili teknikler için ve rehberlerimizi inceleyin.

Shopify Scraping için Thunderbit’i Deneyin

SSS

products.json ile herhangi bir Shopify mağazası çekilebilir mi?

Çoğu Shopify mağazası bu endpoint’i varsayılan olarak sunar — testlerde yaklaşık yüzde 71’i geçerli JSON döndürdü. Özel yapılandırmaları veya ek güvenlik katmanları (Cloudflare, headless kurulumlar) olan bazı mağazalar 404 verebilir ya da isteği engelleyebilir. Hızlı kontrol: {store-url}/products.json adresini tarayıcıda açın. JSON görüyorsanız sorun yok.

Shopify mağazalarını çekmek yasal mı?

Herkese açık ürün verileri (fiyatlar, başlıklar, görseller, açıklamalar) genellikle erişilebilir durumdadır ve hiQ v. LinkedIn gibi emsaller kamuya açık bilgi çekimini destekler. Yine de her zaman ilgili mağazanın kullanım şartlarını ve yerel yasaları kontrol edin. Kişisel veya müşteri verisi çekmeyin ve rate limit’lere uyun.

Bir Shopify mağazasından kaç ürün çekebilirsiniz?

Toplamda kesin bir üst sınır yoktur. ?limit=250&page= ile sayfalama yaparak tüm kataloğu alabilirsiniz. Çok büyük mağazalarda (25.000+ ürün) rate limit’e takılmamak için session reuse ve gecikme kullanın. /meta.json endpoint’i size tam ürün sayısını önceden vererek kaç sayfa beklemeniz gerektiğini gösterir.

products.json ile Shopify Admin API arasındaki fark nedir?

/products.json, herkese açık bir endpoint’tir — kimlik doğrulama gerektirmez, salt okunurdur ve herkes erişebilir. Admin API ise mağaza sahibinin erişim token’ını ister ve siparişler, stok miktarları, müşteri verileri ve yazma yetkisi sağlar. Satış verisi ya da gerçek stok sayıları gerekiyorsa Admin API erişimi gerekir (yani mağaza sahibi olmanız ya da izin almanız gerekir).

Python kullanmadan Shopify verisi çekebilir miyim?

Kesinlikle. gibi araçlar, Chrome uzantısı üzerinden kod yazmadan Shopify mağazalarını çekmenizi sağlar. Sayfalama işlemini otomatik yönetir ve veriyi doğrudan CSV, Excel, Google Sheets, Airtable veya Notion’a aktarır. Başka dilleri tercih eden geliştiriciler için de aynı /products.json endpoint’i JavaScript, Ruby, Go — HTTP isteği atıp JSON ayrıştırabilen herhangi bir dil ile çalışır.

Daha Fazla Bilgi

İçindekiler

Thunderbit’i dene

Lead’leri ve diğer verileri sadece 2 tıkla çek. Yapay zeka destekli.

Thunderbit’i Al Ücretsiz
Yapay zeka ile veri çıkar
Verileri kolayca Google Sheets, Airtable veya Notion’a aktar
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week