eBay Veri Kazıma: API mi, HTML Kazıma mı?
eBay, dünya genelinde 1.7 milyardan fazla aktif listeleme barındıran devasa bir pazar yeridir. Fiyat izleme, satıcı istihbaratı ve rekabet analizi yapan ekipler için bu veri altın madenesidir. Ancak eBay verisine erişmek, resmi API'lerin kota sınırlamaları ve agresif anti-bot sistemleri nedeniyle kolay değildir.
Bu rehberde, eBay Finding/Browse API'lerinin sınırlarını, HTML kazımaya geçiş nedenlerinizi, doğru proxy stratejisini ve çalışan Python kod örneklerini bulacaksınız.
API Kota ve Erişim Sınırlamaları
eBay, geliştiricilere iki temel API sunar:
- Finding API —
https://svcs.ebay.com/services/search/FindingService/v1— Temel uygulama katmanında günde 5.000 çağrı ile sınırlandırılmıştır. - Browse API —
https://api.ebay.com/buy/browse/v1/item_summary/search— Geçerli bir OAuth belirteciyle saniyede ~100 çağrıya izin verir, ancak kategori ağacı geçişleri ve tam ürün özellikleri istediğinizde bu hızla daralır.
Trading API ise oturum açmış satıcılar içindir ve OAuth karmaşıklığı getirir. Daha da önemlisi, API yanıtları her zaman ihtiyacınız olan veriyi içermez:
- Açık artırma geri sayım zamanlayıcıları API'de mevcut değildir
- Kargo maliyetleri yalnızca kısmi olarak döner
- Satıcı geri bildirim detayları (son 12 ay, kategori bazlı) eksiktir
- Bölgesel fiyat farklılıkları (eBay.de vs eBay.com) tek pazar API'siyle yakalanamaz
İşte HTML kazımanın devreye girdiği nokta burasıdır. API kotalarına ulaştığınızda, belirli veri alanları API'den eksik olduğunda veya bölgesel eBay alanlarındaki fiyat farklılıklarını yakalamak istediğinizde, doğrudan sayfa kazıma tek güvenilir yoldur.
| Kriter | Finding/Browse API | HTML Kazıma |
|---|---|---|
| Günlük Kota | 5.000 çağrı (temel) | Proxy havuzuna bağlı |
| Yanıt Formatı | Yapılandırılmış JSON | HTML ayrıştırma gerekli |
| Açık Artırma Verisi | Sınırlı (bitiş zamanı yok) | Tam (geri sayım, teklif sayısı) |
| Kargo Maliyeti | Kısmi | Tam (sayfada gösterilen) |
| Satıcı Geri Bildirimi | Temel skor | Ayrıntılı (son 12 ay, kategoriler) |
| Bölgesel Fiyatlar | Tek pazar | eBay.de, eBay.co.uk vb. |
| Anti-Bot Riski | Yok | Yüksek (PerimeterX, Akamai) |
| Bakım Maliyeti | Düşük | Orta (seçici güncellemeleri) |
API Yanıt Örneği (Kesilmiş)
{
"itemSummaries": [
{
"title": "NVIDIA RTX 4090 Founders Edition",
"price": {"value": "1599.00", "currency": "USD"},
"itemWebUrl": "https://www.ebay.com/itm/123456789",
"seller": {"username": "gpu_seller_99"}
}
],
"total": 2847
}
API yanıtı temizdir — ancak kargo, açık artırma zamanlayıcısı ve satıcı geri bildirim detayları eksiktir.
eBay HTML Yapısı: Hedef Seçiciler
eBay sayfaları yıllar içinde değişmiştir, ancak temel sınıf yapıları görece stabildir. İşte kazıma hedefleriniz ve bunlara karşılık gelen seçiciler.
Arama Sonuçları Izgarası
Arama sonuçları sayfası (/sch/i.html?_nkw=KEYWORD), her listelemeyi .s-item sınıflı bir <div> içinde barındırır. Bu, eBay listing scraper geliştirirken en sık kullanacağınız yapıdır.
| Veri Alanı | CSS Seçici | XPath |
|---|---|---|
| Liste Kabı | .s-item | //div[contains(@class,'s-item')] |
| Başlık | .s-item__title | .//h3[contains(@class,'s-item__title')] |
| Fiyat | .s-item__price | .//span[contains(@class,'s-item__price')] |
| Kargo | .s-item__shipping | .//span[contains(@class,'s-item__shipping')] |
| Teklif Sayısı | .s-item__bid-count | .//span[contains(@class,'s-item__bid-count')] |
| Kalan Süre | .s-item__time-left | .//span[contains(@class,'s-item__time-left')] |
| Liste Bağlantısı | .s-item__link | .//a[contains(@class,'s-item__link')] |
| Buy-It-Now | .s-item__format | .//span[contains(@class,'s-item__format')] |
| Resim | .s-item__image-img | .//img[contains(@class,'s-item__image-img')] |
Liste Detay Sayfası
Tekil ürün sayfası (/itm/ID) daha zengin veri sunar:
| Veri Alanı | CSS Seçici |
|---|---|
| Başlık | #itemTitle |
| Fiyat | .prc veya #prcIsum |
| Miktar | .vi-qtyS |
| Durum | .ux-labelsvalues__values span:first-child |
| Satıcı Adı | .si-content a |
| Satıcı Geri Bildirimi | .si-content .mbg-l |
Satıcı Profil Sayfası
Satıcı profili (/usr/USERNAME) satıcı analitiği için kritiktir:
| Veri Alanı | CSS Seçici |
|---|---|
| Geri Bildirim Skoru | .seller-persona .infocontainer |
| Son 12 Ay Geri Bildirimi | .seller-persona .mbg-l |
| Aktif Listeleme Sayısı | .seller-active-listings |
| Kategoriler | .seller-persona a[href*='/_s'] |
İpucu: eBay HTML yapısı düzenli olarak güncellenir. Seçicilerinizi bir CI testi ile izleyin — haftada bir başarısız olan kazıma, seçici değişikliğine işaret eder. Seçici kırılma oranını izlemek, bakım maliyetini dramatik şekilde düşürür.
Proxy Seçimi: Residential mi, Datacenter mı?
eBay, PerimeterX (şimdi HUMAN) ve Akamai Bot Manager tarafından korunmaktadır. Datacenter IP'leri agresif şekilde engellenir — genellikle ilk birkaç istekten sonra CAPTCHA veya 403 yanıtı alırsınız. Bu nedenle eBay proxy seçiminde residential proxy neredeyse zorunludur.
Neden Residential Proxy?
- Datacenter IP engelleme oranı: %80+ (ilk 5-10 istek içinde)
- Residential IP engelleme oranı: %5-15 (uygun rotasyon ile)
- Mobile proxy engelleme oranı: %3-8 (en düşük, ancak maliyet en yüksek)
Datacenter proxy'ler, residential proxy'lerle karşılaştırıldığında, eBay gibi PerimeterX korumalı sitelerde pratik olarak kullanılamaz. Bütçe kısıtlaması yoksa, residential proxy tek güvenilir seçenektir.
Bölgesel eBay Siteleri İçin Geo-Hedefleme
eBay fiyatları bölgeye göre değişir. Almanya'daki bir GPU fiyatını ABD fiyatıyla karşılaştırmak istiyorsanız, eBay.de'den Alman IP'siyle kazımanız gerekir. ProxyHat ile ülke bazlı hedefleme kullanıcı adı üzerinden yapılır:
# eBay.de için Alman IP
http://user-country-DE:pass@gate.proxyhat.com:8080
# eBay.co.uk için İngiliz IP
http://user-country-GB:pass@gate.proxyhat.com:8080
# eBay.com için ABD IP
http://user-country-US:pass@gate.proxyhat.com:8080
Şehir düzeyinde hedefleme de mümkündür — örneğin Berlin'deki yerel kargo tekliflerini yakalamak için:
http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080
ProxyHat'ın desteklediği tüm lokasyonları lokasyonlar sayfasından inceleyebilirsiniz.
IP Rotasyon Stratejisi
- İstek başına rotasyon: Arama sonuçları sayfaları için uygundur. Her sayfa yeni bir IP ile istenir.
- Yapışkan oturumlar: Liste detay sayfaları veya satıcı profilleri için aynı IP'yi birkaç dakika tutun. ProxyHat oturum bayrağıyla yapılır:
# Aynı IP'yi 10 dakika boyunca koru
http://user-session-abc123:pass@gate.proxyhat.com:8080
Önemli: eBay, tek IP'den dakikada ~30-50 istekten sonra hız sınırlamaya geçer. Her IP için dakikada 20 istek altında kalmayı hedefleyin. Bu eşik, PerimeterX'in davranış modeli tetiklemeden önceki güvenli bölgedir.
Python ile eBay Arama Sonuçlarını Kazımak
Aşağıdaki örnek, ProxyHat residential proxy kullanarak eBay arama sonuçlarını çeker ve .s-item öğelerini yapılandırılmış kayıtlara dönüştürür. Bu, her eBay listing scraper'ın temel yapı taşıdır.
curl ile Hızlı Test
Python koduna geçmeden önce, proxy bağlantınızı doğrulayın:
curl -x http://user-country-US:pass@gate.proxyhat.com:8080 \
"https://www.ebay.com/sch/i.html?_nkw=rtx+4090&_pgn=1" \
-H "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" \
-H "Accept-Language: en-US,en;q=0.9"
Python: Arama Sonuçlarını Çekme ve Ayrıştırma
import requests
from bs4 import BeautifulSoup
import re
import json
import time
PROXY = "http://user-country-US:pass@gate.proxyhat.com:8080"
PROXIES = {"http": PROXY, "https": PROXY}
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"
),n "Accept-Language": "en-US,en;q=0.9",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
}
def fetch_ebay_search(keyword, page=1):
"""eBay arama sonuçları sayfasını çeker."""
url = "https://www.ebay.com/sch/i.html"
params = {"_nkw": keyword, "_pgn": page}
resp = requests.get(
url, params=params, headers=HEADERS,
proxies=PROXIES, timeout=30
)
resp.raise_for_status()
return resp.text
def parse_search_results(html):
"""eBay arama HTML'ini yapılandırılmış kayıtlara dönüştürür."""
soup = BeautifulSoup(html, "html.parser")
items = []
for listing in soup.select(".s-item"):
title_el = listing.select_one(".s-item__title")
# "Shop on eBay" banner'ını atla
if not title_el or "Shop on eBay" in title_el.text:
continue
price_el = listing.select_one(".s-item__price")
shipping_el = listing.select_one(".s-item__shipping")
link_el = listing.select_one(".s-item__link")
bid_el = listing.select_one(".s-item__bid-count")
time_el = listing.select_one(".s-item__time-left")
bin_el = listing.select_one(".s-item__format")
img_el = listing.select_one(".s-item__image-img")
items.append({
"title": title_el.text.strip(),
"price": price_el.text.strip() if price_el else None,
"shipping": shipping_el.text.strip() if shipping_el else None,
"url": link_el["href"] if link_el else None,
"bid_count": bid_el.text.strip() if bid_el else None,
"time_left": time_el.text.strip() if time_el else None,
"is_buy_it_now": bin_el is not None,
"image": img_el["src"] if img_el else None,
})
return items
# Kullanım
html = fetch_ebay_search("rtx 4090", page=1)
results = parse_search_results(html)
print(json.dumps(results[:3], indent=2, ensure_ascii=False))
Beklenen Çıktı (Örnek)
[
{
"title": "NVIDIA GeForce RTX 4090 24GB GDDR6X",
"price": "$1,599.00",
"shipping": "Free shipping",
"url": "https://www.ebay.com/itm/1234567890",
"bid_count": null,
"time_left": null,
"is_buy_it_now": true,
"image": "https://i.ebayimg.com/images/g/abc/s-l225.jpg"
},
{
"title": "NVIDIA RTX 4090 Founders Edition Sealed",
"price": "$1,250.00",
"shipping": "+$15.00 shipping",
"url": "https://www.ebay.com/itm/0987654321",
"bid_count": "23 bids",
"time_left": "2h 15m left",
"is_buy_it_now": false,
"image": "https://i.ebayimg.com/images/g/def/s-l225.jpg"
}
]
Açık Artırma Verilerini İşlemek
eBay açık artırmaları, teklif sayısı ve kalan süre kombinasyonuyla analiz edilebilir. Yüksek teklif sayısı + kısa süre = "sıcak" bir açık artırmadır ve fiyat eğilimlerini anlamak için değerlidir. Bu veri yalnızca HTML'de mevcuttur, API'de değil.
Zamanlayıcı Ayrıştırma ve Sıcak Açık Artırma Tespiti
eBay, kalan süreyi "Xh Xm left" veya "Xd Xh left" formatında gösterir. Bunu tahmini bitiş zamanına dönüştürmek ve teklif yoğunluğuna göre sıcak açık artırma tespiti yapmak için:
from datetime import datetime, timedelta
def parse_auction_time(time_str):
"""eBay 'Xh Xm left' formatını tahmini bitiş zamanına çevirir."""
if not time_str:
return None
days = hours = minutes = 0
d_match = re.search(r"(\d+)d", time_str)
h_match = re.search(r"(\d+)h", time_str)
m_match = re.search(r"(\d+)m", time_str)
if d_match:
days = int(d_match.group(1))
if h_match:
hours = int(h_match.group(1))
if m_match:
minutes = int(m_match.group(1))
return datetime.utcnow() + timedelta(days=days, hours=hours, minutes=minutes)
def is_hot_auction(item):
"""Kısa sürede yüksek teklif yoğunluğu = sıcak açık artırma."""
if not item.get("bid_count") or not item.get("time_left"):
return False
end_time = parse_auction_time(item["time_left"])
bid_match = re.search(r"\d+", item["bid_count"])
if not bid_match:
return False
bids = int(bid_match.group())
time_remaining_hours = max(
(end_time - datetime.utcnow()).total_seconds() / 3600, 0.1
)
# Saat başına >5 teklif = sıcak açık artırma
return (bids / time_remaining_hours) > 5
# Sıcak açık artırmaları filtrele
hot_items = [i for i in results if is_hot_auction(i)]
print(f"Sıcak açık artırma sayısı: {len(hot_items)}")
Buy-It-Now Bayrağı
.s-item__format öğesinin varlığı, listelemenin sabit fiyatlı (Buy-It-Now) olduğunu gösterir. Açık artırma listelemelerinde bu öğe yoktur. Bazı satıcılar her iki seçeneği de sunar — bu durumda hem .s-item__format hem de .s-item__bid-count mevcut olabilir. Kazıma mantığınızda her iki bayrağı da kontrol edin.
Satıcı Analitiği: Feedback ve Kategoriler
Satıcı istihbaratı, yeniden satış ekipleri için kritiktir. Bir satıcının ne sattığını, ne sıklıkla sattığını ve alıcıların memnuniyetini bilmek, ortaklık ve rekabet kararlarını şekillendirir. Web kazıma kullanım senaryolarında satıcı analitiği en değerli veri türlerinden biridir.
Satıcı Profil Sayfasını Kazıma
def scrape_seller_profile(seller_url):
"""Satıcı profil sayfasından geri bildirim ve kategori verisi çeker."""
resp = requests.get(
seller_url, headers=HEADERS,
proxies=PROXIES, timeout=30
)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
# Geri bildirim skoru
fb_score_el = soup.select_one(
".seller-persona .infocontainer .mbg-l"
)
feedback_score = fb_score_el.text.strip() if fb_score_el else "0"
# Son 12 ay geri bildirimi
recent_fb_els = soup.select(
".seller-persona .infocontainer .mbg-l"
)
recent_feedback = (
recent_fb_els[1].text.strip()
if len(recent_fb_els) > 1 else "0"
)
# Aktif listeleme sayısı
active_el = soup.select_one(".seller-active-listings")
active_listings = active_el.text.strip() if active_el else "0"
# Satıcı kategorileri
categories = [
a.text.strip()
for a in soup.select(".seller-persona a[href*='/_s']")
]
return {
"feedback_score": feedback_score,
"recent_feedback_12m": recent_feedback,
"active_listings": active_listings,
"categories": categories,
}
Çapraz Listeleme Desenleri
Bir satıcının birden fazla kategoride aktif olması, stok çeşitliliğini gösterir. Bu veriyi kullanarak:
- Tek kategorili satıcılar: Niş uzman, fiyat baskısı yapabilir
- Çok kategorili satıcılar: Genel tüccar, toplu alım pazarlığı yapılabilir
- Yüksek feedback + çok kategori: Güvenilir toptancı, uzun vadeli ortaklık adayı
Seller Feedback API Alternatifi
eBay'un GetFeedback Trading API çağrısı detaylı geri bildirim verisi sunar, ancak OAuth gerektirir ve günlük çağrı sınırları vardır. Büyük ölçekli satıcı izleme için HTML kazıma daha pratiktir — hem kota sınırı yoktur hem de profil sayfası API'de bulunmayan kategori ve aktif listeleme verisini sunar.
Anti-Bot Sistemleri ve Risk Azaltma
eBay, aşağıdaki anti-bot teknolojilerini kullanır. Her birine karşı uygun strateji uygulamak, scrape eBay operasyonlarınızın kesintisiz çalışması için kritiktir:
| Sistem | Tespit Yöntemi | Azaltma Stratejisi |
|---|---|---|
| PerimeterX (HUMAN) | JS parmak izi, fare hareketi | Residential proxy + gerçekçi User-Agent |
| Akamai Bot Manager | HTTP başlık sırası, TLS parmak izi | Residential IP + doğal başlık sırası |
| Hız Sınırlama | IP başına istek hızı | IP başına dakikada <20 istek |
| CAPTCHA | Şüpheli davranış kalıpları | Rotasyonu yavaşlat, yapışkan oturum kullan |
Pratik öneriler:
- Dakikada 15-20 istek hedefleyin, IP başına
- Yapışkan oturumlar kullanın: tek bir ziyaretçi gibi davranın, aynı oturumda birden fazla sayfa gezin
- User-Agent tutarlılığı sağlayın: her oturum için tek bir UA kullanın, oturumlar arası değiştirin
- Sayfalar arası 1-3 saniye gecikme ekleyin — gerçek kullanıcı davranışını taklit edin
- eBay robots.txt'i kontrol edin:
https://www.ebay.com/robots.txt— sayfaların çoğuDisallowile işaretlenmez, ancak/api/ve/sl/yolları yasaktır
Etik not: eBay'in Hizmet Şartları otomatik veri toplamayı kısıtlar. robots.txt kurallarına uyun, kişisel verileri (satıcı iletişim bilgileri vb.) GDPR/CCPA kapsamında işleyin ve kazıma hacminizi makul tutun. Rekabet istihbaratı için kazıma, birçok yetki alanında yasal bir gri alan olsa da, sorumlu kullanım her zaman en iyi stratejidir.
Performans Metrikleri ve Ölçeklendirme
Büyük ölçekli eBay kazıma operasyonlarında izlemeniz gereken temel metrikler:
- Başarı oranı: Hedef %95+. Düşüş, proxy kalitesi veya seçici değişikliği işaret edebilir
- Ortalama yanıt süresi: Residential proxy ile 2-5 saniye bekleyin. 10 saniye üzeri, IP'nin hız sınırlamaya girdiğini gösterir
- Eşzamanlılık: Her IP için 1-2 eşzamanlı bağlantı. Toplam eşzamanlılık = IP havuzu büyüklüğü × 1.5
Ölçeklendirme için, farklı anahtar kelimeleri farklı proxy oturumlarına dağıtın. Aynı oturumda sıralı olarak sayfalama yapmak, tek bir anahtar kelime için daha güvenilirdir — ancak 50+ anahtar kelime izliyorsanız, her birini bağımsız proxy oturumlarına atayın.
Temel Çıkarımlar
- eBay Finding/Browse API'leri günde 5.000 çağrı ile sınırlandırılmıştır; ölçekli veri ihtiyaçları için HTML kazıma kaçınılmazdır
.s-itemCSS seçicisi, arama sonuçları kazımasının temel yapı taşıdır- Datacenter IP'leri eBay'de %80+ engelleme oranıyla reddedilir; residential proxy zorunludur
- Bölgesel fiyat karşılaştırmaları için geo-hedeflenmiş proxy kullanın (eBay.de → Alman IP, eBay.co.uk → İngiliz IP)
- Açık artırma verisi (teklif sayısı, kalan süre) yalnızca HTML'de mevcuttur, API'de değil
- Satıcı analitiği için profil sayfalarını kazıyın ve kategori/feedback verisini yapılandırın
- IP başına dakikada 20 istek altında kalarak PerimeterX ve Akamai tespitinden kaçının
- Yapışkan oturumlar, tek isteklik rotasyondan daha güvenilirdir — gerçek kullanıcı davranışını taklit eder
ProxyHat'ın residential proxy ağıyla eBay kazıma operasyonunuzu başlatmak için fiyatlandırma sayfamıza göz atın. 190+ ülkede geo-hedeflenmiş IP'lerle hem eBay.com hem de bölgesel eBay sitelerini kesintisiz kazıyabilirsiniz.






