How to scrape ebay with python cover 1 2

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-Agent yang 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.



Share article: