In this Article
Panduan ini menunjukkan cara melakukan scraping eBay dengan Python dari awal hingga akhir: scraper yang berfungsi untuk hasil pencarian, listing individual, varian produk, dan ulasan, beserta konfigurasi anti-bot dan proxy agar scraper tetap berjalan. Anda memerlukan Python 3, beberapa library, dan sekitar 30 menit untuk versi dasarnya. Di akhir panduan, Anda akan memiliki fungsi web scraping eBay yang dapat digunakan kembali dan mengekspor JSON serta CSV yang rapi.
Saya Andrii Byzov, CMO fraksional yang berfokus pada AI dan menjalankan data pipeline e-commerce. eBay adalah target bernilai tinggi, tetapi pertahanannya kuat. Karena itu, panduan cara melakukan scraping eBay ini memadukan kode dengan bagian yang sering dilewatkan panduan lain: pagination, data varian tersembunyi, dan cara menghindari pemblokiran. Ringkasnya, agar scraping eBay aman: kirim header browser asli, gunakan rotating residential proxies, dan patuhi rate limits. Untuk memilih IP yang tepat, lihat panduan kami tentang proxy terbaik untuk scraping eBay.
Fakta Utama
- eBay memiliki dua jenis halaman: hasil pencarian dan listing produk, dengan struktur HTML yang berbeda, sehingga Anda perlu membuat dua scraper.
- Varian (ukuran, warna, penyimpanan) tersembunyi dalam JSON inline, bukan HTML yang terlihat. Anda mengekstraknya dengan regex dan
json.loads(). - Header browser asli adalah hal pertama yang dibutuhkan. Tanpa
User-Agentyang tepat, eBay sering mengembalikan 403 atau halaman kosong, bahkan untuk request sederhana. - Datacenter IP cepat ditandai di eBay; rotating residential proxies mampu menangani volume dan mengembalikan harga yang sesuai wilayah.
- Listing berbeda menurut negara: eBay.com, eBay.co.uk, dan eBay.de menampilkan harga serta pengiriman yang berbeda, jadi geo-targeting penting untuk scraping data eBay yang akurat.
Langkah 1: Siapkan Environment Anda
Buat environment terisolasi dan instal library yang dibutuhkan konfigurasi web scraping eBay Anda. Masing-masing memiliki tugas: requests mengambil halaman, beautifulsoup4 + lxml mengurai HTML, dan httpx menangani request async saat skala Anda bertambah.
# Create an isolated project folder and virtual environment
mkdir ebay-scraper && cd ebay-scraper
python3 -m venv env
source env/bin/activate # Windows: env\Scripts\activate
# requests -> send HTTP requests
# beautifulsoup4 -> parse the returned HTML
# lxml -> fast HTML parser backend for BeautifulSoup
# httpx -> async requests for scaling later
pip install requests beautifulsoup4 lxml httpx
Langkah 2: Pahami Struktur Halaman eBay
Sebelum menulis kode, pahami bahwa eBay memiliki dua jenis halaman yang pada dasarnya berbeda. Scraping eBay secara andal dimulai dengan mengetahui selector yang digunakan masing-masing halaman. Scraping setiap jenis halaman memerlukan selector berbeda. Buka halaman apa pun, tekan F12 (atau klik kanan → Periksa), lalu arahkan kursor ke elemen untuk menemukan class-nya. Peta di bawah ini akan menjadi acuan Anda pada Langkah 3 dan 4.
Halaman Hasil Pencarian
Setiap hasil berada dalam container li.s-item, dengan judul, harga, dan link di dalamnya. Parameter URL _pgn mengatur pagination dan akan Anda perlukan pada Langkah 3.
Halaman Listing Produk
Satu listing menampilkan harga di .x-price-primary, judul di h1 span, dan spesifikasi item pada baris .ux-labels-values. Perhatikan bahwa deskripsi panjang berada dalam iframe#desc_ifr terpisah, yaitu subhalaman yang perlu Anda scrape dengan request tersendiri.
| Data | Selector hasil pencarian | Selector halaman listing |
|---|---|---|
| Container | li.s-item |
— |
| Judul | .s-item__title |
h1 span |
| Harga | .s-item__price |
.x-price-primary |
| Link / gambar | a.s-item__link / .s-item__image img |
— |
| Spesifikasi item | — | .ux-labels-values |
| Deskripsi | — | iframe#desc_ifr |
Langkah 3: Scrape Hasil Pencarian eBay
Scraper pertama menerima query pencarian dan mengembalikan daftar item berisi judul, harga, URL, dan gambar, yang menjadi titik awal bagi sebagian besar proyek web scraping eBay. Tanpa header User-Agent yang tepat, eBay mengembalikan 403 atau halaman kosong bahkan untuk request sederhana ini, jadi sertakan header sejak awal. Anda dapat menyesuaikan pola yang sama untuk melakukan scraping listing eBay dari kata pencarian apa pun.
import requests
from bs4 import BeautifulSoup
from urllib.parse import quote_plus
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9"}
def scrape_search(query, proxies=None):
"""Return a list of eBay search results for a query."""
url = f"https://www.ebay.com/sch/i.html?_nkw={quote_plus(query)}"
html = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
soup = BeautifulSoup(html.text, "lxml")
items = []
for card in soup.select("li.s-item"):
title = card.select_one(".s-item__title")
price = card.select_one(".s-item__price")
link = card.select_one("a.s-item__link")
image = card.select_one(".s-item__image-wrapper img")
if not (title and link):
continue
items.append({
"title": title.get_text(strip=True),
"price": price.get_text(strip=True) if price else None,
"url": link["href"],
"image": image.get("src") if image else None,
})
return items
print(scrape_search("smartphone")[:3])
Menangani Pagination
Satu halaman hasil tidak cukup. Loop ini menaikkan parameter _pgn (halaman 2, 3, … N) dan berhenti saat daftar hasil kosong atau Anda mencapai batas halaman, bagian yang sering tidak dibahas tutorial scraper eBay dengan Python.
from urllib.parse import quote_plus
def scrape_all_pages(query, max_pages=10, proxies=None):
"""Page through results via the _pgn parameter until empty or max_pages."""
all_items = []
for page in range(1, max_pages + 1):
url = (f"https://www.ebay.com/sch/i.html?_nkw={quote_plus(query)}"
f"&_pgn={page}")
html = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
soup = BeautifulSoup(html.text, "lxml")
cards = soup.select("li.s-item")
if not cards: # no more results -> stop
break
for card in cards:
title = card.select_one(".s-item__title")
link = card.select_one("a.s-item__link")
if title and link:
all_items.append({"title": title.get_text(strip=True),
"url": link["href"]})
return all_items
Step 4 — Scrape Halaman Listing Produk
Saat Anda melakukan scraping listing eBay satu per satu, parse_product(url) menerima satu URL listing dan mengembalikan field terstruktur: judul, harga, kondisi, penjual, pengiriman, serta tabel spesifikasi item yang setiap barisnya berupa pasangan key/value. Ini adalah inti scraping data eBay pada level produk.
def parse_product(url, proxies=None):
"""Scrape a single eBay listing page."""
html = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
soup = BeautifulSoup(html.text, "lxml")
def text(sel):
el = soup.select_one(sel)
return el.get_text(strip=True) if el else None
# item specifics live in a label/value table
specifics = {}
for row in soup.select(".ux-labels-values"):
label = row.select_one(".ux-labels-values__labels")
value = row.select_one(".ux-labels-values__values")
if label and value:
specifics[label.get_text(strip=True)] = value.get_text(strip=True)
return {
"title": text("h1 span"),
"price": text(".x-price-primary"),
"condition": text(".x-item-condition-text .ux-textspans"),
"seller": text(".x-sellercard-atf__info__about-seller"),
"shipping": text(".ux-labels-values--shipping .ux-textspans"),
"item_specifics": specifics,
}
Mengekstrak Varian Produk (Data MSKU)
eBay menyimpan opsi varian produk, seperti warna, ukuran, dan penyimpanan, bukan dalam HTML yang terlihat melainkan di dalam objek JSON inline (MSKU) pada tag <script>. Temukan JSON tersebut dan uraikan dengan json.loads(). Key dan strukturnya dapat berubah seiring waktu, jadi jadikan kode di bawah sebagai titik awal dan sesuaikan dengan yang Anda lihat di DevTools. Kode ini mengembalikan opsi varian (nama/value), bagian yang sering dilewatkan kompetitor.
import re, json
def parse_variants(url, proxies=None):
"""eBay keeps multi-SKU variant options (size, colour, storage) in an inline
JSON blob rather than visible HTML. The exact key and shape change over time,
so treat the pattern below as a starting point and adjust it to the page you
inspect in DevTools. This returns the option name/value pairs, not full
price-per-combination data."""
html = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30).text
# find the inline state object, then load it with a balanced-brace slice
start = html.find('"MSKU"')
if start == -1:
return []
brace = html.find("{", start)
depth, end = 0, brace
for i in range(brace, len(html)):
depth += (html[i] == "{") - (html[i] == "}")
if depth == 0:
end = i + 1
break
try:
data = json.loads(html[brace:end])
except json.JSONDecodeError:
return []
return [{"name": v.get("displayName"), "value": v.get("valueName")}
for v in data.get("menuItemMap", {}).values()]
Langkah 5: Scrape Ulasan Produk eBay
Saat melakukan scraping ulasan eBay, perhatikan bahwa ulasan tersebut adalah ulasan produk/katalog pada URL terpisah, bukan di setiap halaman listing, dan tidak setiap listing memilikinya. Anda memperoleh URL ulasan dari ID produk/katalog yang ditemukan pada listing, lalu mengambil rating, teks, tanggal, dan penulis. Anggap endpoint di bawah sebagai ilustrasi dan pastikan path saat ini di DevTools.
def scrape_reviews(item_id, proxies=None):
"""Reviews live on a separate URL keyed by the item ID."""
url = f"https://www.ebay.com/urw/{item_id}/product-reviews"
html = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
soup = BeautifulSoup(html.text, "lxml")
reviews = []
for r in soup.select(".ebay-review-section"):
rating = r.select_one(".star-rating")
body = r.select_one(".review-item-content")
date = r.select_one(".review-item-date")
author = r.select_one(".review-item-author")
reviews.append({
"rating": rating.get("aria-label") if rating else None,
"text": body.get_text(strip=True) if body else None,
"date": date.get_text(strip=True) if date else None,
"author": author.get_text(strip=True) if author else None,
})
return reviews
Langkah 6: Ekspor Data ke JSON dan CSV
Simpan hasil Anda dalam kedua format secara berdampingan: JSON mempertahankan struktur bertingkat, yang berguna untuk varian dan spesifikasi, sedangkan CSV datar dan dapat langsung dibuka di Excel atau Google Sheets.
import json, csv
results = scrape_search("smartphone")
# Option A - JSON (keeps nested structure)
with open("ebay.json", "w", encoding="utf-8") as f:
json.dump(results, f, indent=2, ensure_ascii=False)
# Option B - CSV (flat, opens in Excel/Sheets)
if results:
with open("ebay.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=results[0].keys())
writer.writeheader()
writer.writerows(results)
Langkah 7: Melewati Perlindungan Anti-Bot eBay
eBay melindungi listing dengan lapisan mekanisme: penilaian reputasi IP, rate limiting (HTTP 429), pemblokiran lunak (respons 200 dengan hasil kosong), dan CAPTCHA. Anda tidak akan mengatasi semuanya dengan satu cara, tetapi header dan IP yang tepat dapat menangani kasus umum web scraping eBay dalam skala yang wajar.
Atur Header yang Tepat
Kirim set header yang lengkap dan realistis, bukan hanya User-Agent. Setiap header menurunkan risiko pemblokiran: tidak adanya Accept-Language atau Referer merupakan ciri bot yang umum. Untuk pekerjaan yang lebih besar, gunakan rotating User-Agent dari sebuah daftar.
HEADERS = {
# identify as a real desktop browser - eBay returns 403/empty without this
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9", # match the locale you target
"Accept-Encoding": "gzip, deflate, br", # accept compressed responses
"Referer": "https://www.ebay.com/", # look like in-site navigation
"Connection": "keep-alive",
}
# rotate the User-Agent across a list for larger jobs
import random
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Version/17.0 Safari/605.1.15",
]
HEADERS["User-Agent"] = random.choice(USER_AGENTS)
Gunakan Rotating Residential Proxies
Header tidak cukup untuk volume besar. eBay menilai reputasi IP, dan datacenter proxies jauh lebih cepat ditandai dibandingkan residential proxies. Gunakan residential IP rotating untuk scraping pencarian bervolume tinggi (IP baru untuk setiap request) dan sesi sticky untuk alur listing atau lelang yang memerlukan sesi stabil. DataImpulse residential proxies berharga $1/GB, pay-as-you-go, dan dapat langsung digunakan pada pemanggilan requests.
# Route requests through DataImpulse rotating residential proxies
proxies = {
"http": "http://LOGIN:[email protected]:823",
"https": "http://LOGIN:[email protected]:823",
}
html = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
Geo-targeting: Scraping Data eBay Khusus Wilayah
Listing eBay berbeda menurut negara: eBay.com, eBay.co.uk, dan eBay.de mengembalikan harga, ketersediaan, dan pengiriman yang berbeda untuk produk yang sama. Untuk melihat data yang dilihat pembeli di negara tertentu, arahkan request melalui proxy yang berlokasi di sana. DataImpulse memiliki residential IP di 195 negara, termasuk targeting tingkat negara bagian AS, sehingga scraping data eBay Anda mencerminkan pasar yang tepat. Pendekatan yang sama mendukung perbandingan harga lintas wilayah.
Langkah 8: Tingkatkan Skala Scraper eBay Anda
Tiga tingkat berikut mengubah script dasar menjadi cara siap produksi untuk melakukan scraping eBay dengan Python dalam skala besar, berdasarkan kompleksitas yang meningkat: jeda acak antar-request agar tetap di bawah rate limits, logika retry dengan exponential backoff untuk menangani respons 429/403, dan pengumpulan async dengan httpx + asyncio untuk volume paralel.
import time, random, asyncio, httpx
# 1) Basic pacing - a random delay between requests
def polite_get(url, **kw):
time.sleep(random.uniform(1, 3))
return requests.get(url, headers=HEADERS, timeout=30, **kw)
# 2) Retry with exponential backoff on 429/403
def get_with_retry(url, retries=4, **kw):
for attempt in range(retries):
r = requests.get(url, headers=HEADERS, timeout=30, **kw)
if r.status_code not in (429, 403):
return r
time.sleep(2 ** attempt + random.random()) # 1s, 2s, 4s, 8s ...
return r
# 3) Async collection for high volume (httpx >=0.28 uses proxy=, not proxies=)
async def scrape_many(urls, proxy=None):
async with httpx.AsyncClient(headers=HEADERS, proxy=proxy, timeout=30) as client:
tasks = [client.get(u) for u in urls]
return await asyncio.gather(*tasks)
Pertanyaan yang Sering Diajukan
Apakah scraping eBay legal?
Tergantung situasinya. Scraping data yang tersedia untuk umum dapat legal dalam beberapa konteks, tetapi Perjanjian Pengguna eBay membatasi akses otomatis, termasuk bot, scraper, dan alat data mining, tanpa izin sebelumnya. Karena itu, scraping dapat melanggar ketentuan mereka dan menimbulkan risiko hukum. Penggunaan proxy sendiri legal. Patuhi rate limits, jangan melakukan scraping di balik login, hindari data pribadi, dan mintalah nasihat hukum untuk penggunaan komersial. Ini adalah informasi umum, bukan nasihat hukum. Lihat panduan kami tentang legalitas web scraping.
Apakah saya memerlukan proxy untuk scraping eBay?
Untuk segelintir request, tidak. Untuk volume yang nyata, ya. eBay menilai reputasi IP dan menerapkan rate limiting secara ketat, sehingga satu IP cepat diblokir. Rotating residential proxies menyebarkan request ke banyak IP dan memungkinkan Anda menargetkan negara tertentu untuk memperoleh harga yang sesuai wilayah.
Bagaimana cara melakukan scraping varian produk eBay?
Varian seperti ukuran dan warna tidak ada dalam HTML yang terlihat. eBay menyimpannya dalam objek JSON inline (MSKU) di dalam tag script. Temukan objek tersebut dengan re.search() dan uraikan dengan json.loads(), seperti yang ditunjukkan pada Langkah 4.
Mengapa scraper eBay saya mengembalikan hasil kosong?
Penyebabnya paling sering adalah header. Tanpa User-Agent browser asli, serta idealnya Accept-Language dan Referer, eBay sering mengembalikan 403 atau 200 dengan body kosong. Tambahkan set header lengkap dari Langkah 7. Jika masalah berlanjut, kemungkinan Anda terkena rate limiting atau IP Anda ditandai, jadi perlambat request dan arahkan melalui residential proxy.
Bagaimana cara menangani pagination eBay di Python?
Naikkan parameter URL _pgn (&_pgn=2, 3, …) dalam loop dan berhenti saat container hasil (li.s-item) kosong atau Anda mencapai batas halaman, seperti pada fungsi pagination di Langkah 3.
Kesimpulan
Itulah cara melakukan scraping eBay dengan Python dari awal hingga akhir: scraper hasil pencarian dan listing, pagination, ekstraksi varian tersembunyi, ulasan, ekspor JSON/CSV, serta header dan rotating residential proxies yang menjaga konfigurasi scraper eBay dengan Python Anda tetap berjalan. Mulailah dari scraper pencarian sederhana, lalu tambahkan pagination, header anti-bot, dan peningkatan skala seiring volume Anda bertambah. Untuk IP yang tepat, lihat proxy terbaik untuk scraping eBay.
Terakhir diperbarui: 24 Juni 2026.
