Etsy Veri Çekme Rehberi: Niş Araştırma ve POD İçin Pratik Kılavuz

Etsy'den nasıl veri çekilir? Arama, listeleme ve mağaza sayfalarının yapısı, Cloudflare koruması, residential proxy rotasyonu ve Python örnekleriyle kapsamlı rehber.

Etsy Veri Çekme Rehberi: Niş Araştırma ve POD İçin Pratik Kılavuz

Etsy Veri Çekme: API mi, HTML mi?

Etsy, bir e-commerce API'si sunar ancak bu API 2018'den beri yeni başvurulara kapalıdır. Açık API'ler yalnızca kendi uygulamanızın satış verilerine erişir — rakip mağazaları veya arama sonuçlarını çekemezsiniz. Bu nedenle, niş araştırması ve POD (Print-on-Demand) analizleri yapan ekipler için pratik yol HTML kazıma (web scraping)dir.

Etsy'nin sayfa yapısı oldukça tutarlıdır: arama sonuçları listeleme kartlarından oluşur, her kart bir detay sayfasına bağlanır ve her detay sayfası bir mağaza profiline yönlendirir. Bu üç katmanlı yapı, sistematik veri çekme için idealdir — ancak Cloudflare koruması ve rate limitleri nedeniyle residential proxy kullanımı zorunludur.

Etsy'nin Sayfa Yapısı ve Veri Modeli

Arama Sonuç Sayfaları

Etsy arama URL'leri basit bir yapıya sahiptir:

https://www.etsy.com/search?q=vintage+cat+shirt&ref=search_bar

Her arama sayfası 48 listeleme kartı (<div data-listing-id="...">) render eder. Sayfalama &page=2 parametresiyle çalışır. Kartların içinde şu veriler bulunur:

  • listing_id: data-listing-id attribute'unda
  • Başlık: h3 elementi, class v2listing-card__info
  • Fiyat: span elementi, class currency-value
  • Mağaza adı: a elementi, mağaza linkinde
  • Resim URL: img elementi, src attribute'unda

Listeleme Detay Sayfaları

Her listeleme detay sayfası şu yapıda: https://www.etsy.com/listing/123456789/title-slug

Detay sayfasında çekilebilecek kritik veriler:

  • Açıklama: div[data-appearance-id="description"]
  • Fiyat: p.wt-text-title-01 veya benzeri class
  • Değerlendirme sayısı ve yıldız: JSON-LD Product schema'sında
  • Sevkiyat süresi: div[data-appears-component-name="shipping"]
  • Mağaza bilgisi: Sidebar'da mağaza adı ve satış sayısı

Mağaza Sayfaları

Mağaza URL formatı: https://www.etsy.com/shop/ShopName

Mağaza sayfasında:

  • Satış sayısı: "x sales" badge'i, span içinde
  • Değerlendirme sayısı: Yıldız ve yorum sayısı
  • İlan sayısı: Tüm ilanları listeleme linkinden
  • Mağaza açılış tarihi: About bölümünde

Kategori Ağacı

Etsy'nin kategori yapısı hiyerarşiktir: https://www.etsy.com/c/clothing/shirts. Ana kategoriler navbar'da, alt kategoriler dropdown menülerde listelenir. Kategori sayfaları arama sayfalarıyla aynı kart yapısını kullanır, ancak q parametresi yerine c path segment'i kullanılır.

Etsy'nin Anti-Bot Koruması: Cloudflare ve Rate Limitler

Etsy, Cloudflare behind-the-edge koruması kullanır. Bu, şunları ifade eder:

  • JavaScript challenge: İlk isteklerde Cloudflare interstitial sayfası çıkar. Headless tarayıcılar (Puppeteer, Playwright) bu challenge'ı geçebilir ancak saf HTTP istekleri genellikle 403 alır.
  • Rate limiting: Aynı IP'den dakikada ~30-40 istek sonrası soft-ban başlar. Cloudflare 1020 (rate limit) veya 403 döner.
  • Browser fingerprinting: TLS parmak izi, header sıralaması ve JavaScript execution sonuçları kontrol edilir.

Neden Residential Proxy?

Datacenter IP'leri Cloudflare tarafından hızlıca tanınır ve bloklanır. Residential proxy kullanmak, trafiğin gerçek kullanıcı ISP'lerinden gelmesini sağlar ve bloklanma riskini dramatik şekilde azaltır.

Proxy TipiEtsy Başarı OranıOrtalama LatencyFiyat AralığıÖneri
Datacenter%10-30Düşük (~200ms)$0.5-1/GBÖnerilmez
Residential (Rotating)%85-95Orta (~800ms)$3-7/GBEtsy için ideal
Mobile (3G/4G)%95+Yüksek (~1.5s)$5-12/GBAşırı korumalı sayfalar

ProxyHat residential proxy'leri, Etsy scraping için uygun fiyatlı ve güvenilir bir çözüm sunar. ProxyHat fiyatlandırma sayfasından planları inceleyebilirsiniz.

Etsy Niş Araştırma: Hangi Verileri Çekmelisiniz?

POD girişimcileri ve marketplace araştırma ekipleri genellikle şu üç temel metriği hedefler:

1. Trend Arama Terimleri

Etsy'nin arama otomatik tamamlama endpoint'i trend terimleri yakalamak için kullanışlıdır:

https://www.etsy.com/api/v3/ajax/member/search-suggestions?query=vintage+cat

Bu endpoint, JSON formatında öneri terimleri döner. Her öneri, kullanıcıların gerçekten aradığı bir terimi temsil eder. Birden fazla seed kelime ile bu endpoint'i tarayarak niş fikirleri üretebilirsiniz.

2. Niş Başına Satıcı Sayısı

Belirli bir anahtar kelime için arama yapın ve kaç farklı mağaza adı göründüğünü sayın. Düşük satıcı sayısı + yüksek listing sayısı = potansiyel altın niş. Her arama sayfasında benzersiz mağaza adlarını toplayın ve birden fazla sayfa tarayarak istatistiği genişletin.

3. Ortalama Fiyat Noktaları

Her listeleme kartındaki fiyat bilgisini çekerek, belirli bir nişteki ortalama fiyat, medyan fiyat ve fiyat aralığını hesaplayın. POD ürünleri için $15-35 aralığı tipiktir; bu aralığın üzerinde fiyatlandırma yapan nişler, daha yüksek kar marjı vaat eder.

Python ile Etsy Arama Sonuçlarını Çekme

Aşağıdaki örnek, ProxyHat residential proxy'leriyle Etsy arama sonuçlarını çeker, listeleme kartlarını parse eder ve ardından her ilanın detay sayfasını ziyaret eder.

import requests
from bs4 import BeautifulSoup
import time
import random

# ProxyHat residential proxy yapılandırması
PROXY_USER = "user-country-US-session-abc123"
PROXY_PASS = "your_password"
PROXY_URL = f"http://{PROXY_USER}:{PROXY_PASS}@gate.proxyhat.com:8080"
PROXIES = {"http": PROXY_URL, "https": PROXY_URL}

HEADERS = {
    "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",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
}

def fetch_search_results(keyword, page=1):
    """Etsy arama sonuçlarını çek ve listeleme kartlarını parse et."""
    url = "https://www.etsy.com/search"
    params = {"q": keyword, "page": page}
    resp = requests.get(url, params=params, headers=HEADERS,
                        proxies=PROXIES, timeout=30)
    resp.raise_for_status()
    soup = BeautifulSoup(resp.text, "html.parser")

    listings = []
    cards = soup.select("div[data-listing-id]")
    for card in cards:
        listing_id = card.get("data-listing-id", "")
        title_el = card.select_one("h3")
        price_el = card.select_one("span.currency-value")
        shop_el = card.select_one("a[href*='/shop/']")
        img_el = card.select_one("img")

        listings.append({
            "listing_id": listing_id,
            "title": title_el.get_text(strip=True) if title_el else "",
            "price": price_el.get_text(strip=True) if price_el else "",
            "shop_name": shop_el.get_text(strip=True) if shop_el else "",
            "image_url": img_el.get("src", "") if img_el else "",
        })
    return listings


def fetch_listing_detail(listing_id, title_slug):
    """Tek bir listeleme detay sayfasını çek."""
    url = f"https://www.etsy.com/listing/{listing_id}/{title_slug}"
    resp = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=30)
    resp.raise_for_status()
    soup = BeautifulSoup(resp.text, "html.parser")

    # JSON-LD schema'sından ürün verisini çıkar
    script = soup.find("script", type="application/ld+json")
    description_el = soup.select_one("div[data-appearance-id='description']")
    sales_el = soup.select_one("span[class*='sales']")

    return {
        "url": url,
        "description": description_el.get_text(strip=True)[:500] if description_el else "",
        "sales_badge": sales_el.get_text(strip=True) if sales_el else "",
    }


# Ana akış
keyword = "vintage cat shirt"
all_listings = []n
for page in range(1, 4):  # İlk 3 sayfa
    print(f"Sayfa {page} çekiliyor...")
    listings = fetch_search_results(keyword, page=page)
    all_listings.extend(listings)
    time.sleep(random.uniform(3, 6))  # Rate limit koruması

print(f"Toplam {len(all_listings)} listeleme bulundu.")

# İlk 5 ilanın detayını çek (proxy rotasyonu session flag'i ile)
for listing in all_listings[:5]:
    slug = listing["title"].lower().replace(" ", "-")[:60]
    detail = fetch_listing_detail(listing["listing_id"], slug)
    print(f"Detay: {detail}")
    time.sleep(random.uniform(4, 8))

Not: ProxyHat kullanıcı adında session-abc123 flag'i kullandığınızda, aynı session ID'si ile giden istekler aynı IP'den çıkar (sticky session). Farklı session ID'leri kullanarak IP rotasyonu sağlarsınız. Her detay sayfası isteği için yeni bir session ID üretmek, per-request rotasyon sağlar.

Proxy Rotasyonu ile IP Yönetimi

Etsy'de bloklanmamak için IP rotasyonu kritiktir. ProxyHat'ın username flag sistemiyle rotasyonu kontrol edebilirsiniz:

import uuid

def get_rotating_proxy_url(country="US"):
    """Her çağrıda yeni bir session ID ile farklı residential IP al."""
    session_id = uuid.uuid4().hex[:12]
    username = f"user-country-{country}-session-{session_id}"
    return f"http://{username}:{PROXY_PASS}@gate.proxyhat.com:8080"

# Kullanım
for listing in all_listings[:20]:
    proxy_url = get_rotating_proxy_url(country="US")
    proxies = {"http": proxy_url, "https": proxy_url}
    resp = requests.get(
        f"https://www.etsy.com/listing/{listing['listing_id']}/x",
        headers=HEADERS,
        proxies=proxies,
        timeout=30
    )
    print(f"Status: {resp.status_code} | IP rotasyonu: session-{session_id}")
    time.sleep(random.uniform(2, 5))

Geo-targeting için ülke kodunu değiştirebilirsiniz: country-DE Almanya, country-GB İngiltere, country-TR Türkiye IP'leri verir. Bu, farklı pazarlardaki fiyatları ve ürünleri karşılaştırmak için değerlidir. Mevcut lokasyonları ProxyHat lokasyonlar sayfasından kontrol edebilirsiniz.

Mağaza Analitiği: Satış Sayısı ve Değerlendirmeler

Etsy, mağaza sayfalarında yaklaşık satış sayısını "x sales" badge'i olarak gösterir. Bu veri, bir mağazanın büyüklüğünü ve nişin potansiyel hacmini anlamak için değerlidir.

Satış Sayısı Çekme

Mağaza sayfasındaki satış badge'i genellikle şu yapıda:

<span class="wt-text-caption-01">
  1,234 Sales
</span>

Bu elementi parse ederek satış sayısını çıkarabilirsiniz:

def fetch_shop_analytics(shop_name):
    """Mağaza satış sayısı ve değerlendirme bilgisini çek."""
    session_id = uuid.uuid4().hex[:12]
    username = f"user-country-US-session-{session_id}"
    proxy_url = f"http://{username}:{PROXY_PASS}@gate.proxyhat.com:8080"
    proxies = {"http": proxy_url, "https": proxy_url}

    url = f"https://www.etsy.com/shop/{shop_name}"
    resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
    soup = BeautifulSoup(resp.text, "html.parser")

    # Satış sayısı badge'i
    sales_text = ""
    for span in soup.find_all("span", string=lambda t: t and "Sales" in t):
        sales_text = span.get_text(strip=True)
        break

    # JSON-LD'den değerlendirme
    script = soup.find("script", type="application/ld+json")
    review_count = 0
    rating = 0.0
    if script:
        import json
        try:
            data = json.loads(script.string)
            review_count = data.get("aggregateRating", {}).get("reviewCount", 0)
            rating = data.get("aggregateRating", {}).get("ratingValue", 0.0)
        except (json.JSONDecodeError, AttributeError):
            pass

    # İlan sayısı
    listing_count = len(soup.select("div[data-listing-id]"))

    return {
        "shop_name": shop_name,
        "sales_text": sales_text,
        "review_count": review_count,
        "rating": rating,
        "listing_count_on_page": listing_count,
    }

# Örnek kullanım
analytics = fetch_shop_analytics("ExampleShopName")
print(analytics)
# {'shop_name': 'ExampleShopName', 'sales_text': '1,234 Sales',
#  'review_count': 856, 'rating': 4.8, 'listing_count_on_page': 48}

Değerlendirmeler (Reviews)

Etsy değerlendirmeleri mağaza sayfasında ve listeleme detay sayfalarında görünür. Her değerlendirme şunları içerir:

  • Yıldız sayısı (1-5)
  • Yorum metni
  • Değerlendirenin adı
  • Tarih

Değerlendirmeler dinamik olarak yüklenir (lazy load), bu nedenle tüm yorumları çekmek için scroll simülasyonu yapan bir headless browser (Playwright/Puppeteer) gerekebilir. Ancak ilk sayfa yüklemesinde görünen yorumlar HTML'de mevcuttur.

Etsy Rate Limit Eşikleri ve Stratejileri

Pratik deneyimlere dayanan rate limit eşikleri:

  • Aynı IP, dakikada ~30 istek: Cloudflare soft-ban başlar, 10-30 dakika sonra kalkar.
  • Aynı IP, saatte ~100+ istek: Cloudflare hard-ban, CAPTCHA challenge zorunlu.
  • Aynı session, 5 dakikada ~50 istek: Etsy dahili throttle başlar, 429 dönebilir.

Önerilen strateji:

  • Her istek arasında 3-8 saniye rastgele bekleme ekleyin.
  • Her 50 istekte proxy session ID'sini değiştirin (yeni IP).
  • Günde aynı keyword için max 500-1000 istek limiti koyun.
  • Gece saatlerinde (EST 22:00-06:00) daha yoğun çekim yapın; Cloudflare daha gevşek davranır.

Etik Hususlar: Küçük İşletmelere Saygı

Etsy'deki satıcıların büyük çoğunluğu bağımsız küçük işletmelerdir — evinde çalışan sanatçılar, el yapımı ürün satan zanaatkarlar. Bu gerçek, scraping yaklaşımınızı şekillendirmelidir:

  • Araştırma için çekin, kopyalamayın: Trend analizi, fiyat karşılaştırması ve niş keşfi için veri kullanın. Başkasının tasarımını veya ürün fotoğrafını kopyalamak ahlaksızdır ve telif hakkı ihlalidir.
  • robots.txt'e saygı gösterin: Etsy'nin robots.txt dosyasını kontrol edin ve yasaklanmış path'leri taramayın.
  • Denkleyici yük bırakmayın: Agresif scraping, Etsy'nin sunucularını yorar ve tüm kullanıcı deneyimini bozar. Makul hızda çekin.
  • GDPR ve CCPA: Satıcı isimleri ve değerlendirmeler kişisel veri olabilir. Kişisel verileri depolarken ilgili düzenlemelere uyun.
  • POD için ilham alın: Hangi nişlerin yükselişte olduğunu ve hangi fiyat noktalarının çalıştığını anlamak için veriyi kullanın, ardından kendi özgün tasarımlarınızı oluşturun.

Etsy scraping, bir araştırma aracıdır — bir kopyalama aracı değil. En değerli veri, hangi nişlerin boş olduğunu ve hangi ihtiyaçların karşılanmadığını gösteren veridir.

curl ile Hızlı Test

Python script yazmadan önce Etsy'nin yanıt yapısını test etmek için ProxyHat proxy'sini curl ile kullanabilirsiniz:

curl -x http://user-country-US-session-test1:your_password@gate.proxyhat.com:8080 \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
  -H "Accept: text/html,application/xhtml+xml" \
  "https://www.etsy.com/search?q=vintage+cat+shirt" \
  -o etsy_search.html -w "\nHTTP Status: %{http_code}\nTime: %{time_total}s\n"

200 yanıtı alırsanız, proxy çalışıyor ve Cloudflare challenge'ı geçiyordur. 403 veya 503 alırsanız, session ID'yi değiştirmeyi veya User-Agent'ı güncellemeyi deneyin.

Node.js ile Etsy Scraping

Node.js ekosistemini tercih edenler için ProxyHat proxy kullanımı:

const axios = require('axios');
const { v4: uuidv4 } = require('uuid');

const PROXY_PASS = 'your_password';
const sessionId = uuidv4().hex().slice(0, 12);
const proxyUrl = `http://user-country-US-session-${sessionId}:${PROXY_PASS}@gate.proxyhat.com:8080`;

async function fetchEtsySearch(keyword) {
  const response = await axios.get('https://www.etsy.com/search', {
    params: { q: keyword, page: 1 },
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
      'Accept': 'text/html,application/xhtml+xml',
    },
    proxy: {
      host: 'gate.proxyhat.com',
      port: 8080,
      auth: { username: `user-country-US-session-${sessionId}`, password: PROXY_PASS },
    },
    timeout: 30000,
  });
  console.log(`Status: ${response.status}, Length: ${response.data.length}`);
  return response.data;
}

fetchEtsySearch('vintage cat shirt').catch(console.error);

Örnek Etsy Arama Yanıtı (Kısaltılmış)

Arama sonuçları HTML'inden çıkarılan tipik veri yapısı:

{
  "keyword": "vintage cat shirt",
  "page": 1,
  "listings": [
    {
      "listing_id": "987654321",
      "title": "Retro Cat T-Shirt - Vintage Style Graphic Tee",
      "price": "$22.99",
      "shop_name": "CatPrintStudio",
      "image_url": "https://i.etsystatic.com/.../il_340x270.123.jpg"
    },
    {
      "listing_id": "123456789",
      "title": "Vintage Cat Lover Shirt - 90s Aesthetic",
      "price": "$18.50",
      "shop_name": "RetroPaws",
      "image_url": "https://i.etsystatic.com/.../il_340x270.456.jpg"
    }
  ],
  "total_on_page": 48,
  "scraped_at": "2025-07-15T10:30:00Z"
}

Key Takeaways

  • Etsy API kapalıdır, HTML scraping tek pratik yol — ancak Cloudflare nedeniyle residential proxy zorunludur.
  • Arama kartları data-listing-id attribute'u ve h3 başlık elementleri ile parse edilir.
  • Mağaza satış sayısı "x sales" badge'inden çekilir; bu veri niş hacim analizi için altın değerindedir.
  • Rate limit: Aynı IP'de dakikada ~30 istek üstü Cloudflare soft-ban başlatır. Her 50 istekte proxy rotasyonu yapın.
  • ProxyHat residential proxy ile gate.proxyhat.com:8080 üzerinden ülke ve session bazlı rotasyon sağlayabilirsiniz.
  • Etik çizgiyi koruyun: Araştırma için çekin, tasarım kopyalamayın. Etsy satıcıları küçük işletmelerdir.

Etsy scraping projenize başlamadan önce web scraping kullanım senaryolarımızı ve ProxyHat fiyatlandırma planlarını inceleyin. Residential proxy'ler ile güvenilir, ölçeklenebilir ve etik bir şekilde Etsy verisi çekebilirsiniz.

Başlamaya hazır mısınız?

148+ ülkede 50M+ konut IP'sine AI destekli filtreleme ile erişin.

Fiyatlandırmayı GörüntüleKonut Proxy'leri
← Bloga Dön