คู่มือสอนดึงข้อมูล eBay จำนวนไม่น้อยมักอายุสั้นราว 3 เดือน และผมรู้เรื่องนี้ดี เพราะทีมของเราที่ Thunderbit เห็นนักพัฒนาหมุนเวียนไปกับโค้ดตัวอย่างที่ใช้ไม่ได้อีกต่อไป, CSS selector ที่ล้าสมัย และ GitHub repo ที่เหมือนจะใช้ได้ แต่จริง ๆ หยุดทำงานไปตั้งแต่ eBay เปลี่ยนหน้าดีไซน์รอบที่สองแล้ว
eBay มีรายการสินค้าแบบสดอยู่ราว 2.5 พันล้านรายการ — เป็นชุดข้อมูลราคาสินค้าแบบ long-tail ที่ใหญ่ที่สุดบนเว็บสาธารณะรองจาก Amazon ข้อมูลชุดนี้เป็นพลังเบื้องหลังทุกอย่าง ตั้งแต่การตั้งราคาสำหรับพ่อค้ารีเซล ไปจนถึงการวิเคราะห์คู่แข่ง แต่การเข้าถึงข้อมูลนี้ด้วยโปรแกรมไม่ใช่เรื่องง่าย เพราะมันเปลี่ยนตลอดเวลา: หน้าเว็บของ eBay ที่สร้างด้วย React เปลี่ยนชื่อคลาส CSS อยู่เรื่อย ๆ, มีการทำ A/B test ที่ส่งโครงสร้าง DOM ต่างกันให้ผู้ใช้แต่ละกลุ่ม และ Akamai Bot Manager ก็ยืนขวางอยู่ระหว่างคุณกับ HTML คู่มือนี้จะให้โค้ด Python ที่ใช้ได้ในตอนนี้ อธิบายว่าทำไมตัวดึงข้อมูลถึงพัง เพื่อให้คุณสร้างตัวที่ทนทานได้ ช่วยเปรียบเทียบอย่างตรงไปตรงมาระหว่าง eBay API กับการสแครป และยังมีทางออกแบบไม่ต้องเขียนโค้ดสำหรับวันที่ Python อาจไม่คุ้มกับการตั้งค่า
การดึงข้อมูล eBay ด้วย Python หมายถึงอะไร?
การดึงข้อมูล eBay ด้วย Python คือการเขียนสคริปต์เพื่อดาวน์โหลดหน้าเว็บของ eBay แบบอัตโนมัติ จากนั้นแยก HTML (หรือ JSON ที่ซ่อนอยู่) ออกมา แล้วดึงข้อมูลที่มีโครงสร้าง เช่น ชื่อสินค้า ราคา ข้อมูลผู้ขาย วันที่ขาย รายละเอียดตัวเลือกสินค้า ให้ออกมาเป็นรูปแบบที่ใช้งานต่อได้จริง เช่น CSV, สเปรดชีต หรือฐานข้อมูล
คุณสามารถดึงข้อมูลจากหน้า eBay ได้หลายประเภท:
- หน้าผลการค้นหา (เช่น รายการ "AirPods Pro" ทั้งหมด)
- หน้ารายละเอียดสินค้ารายชิ้น (สเปกเต็ม รูปภาพ ข้อมูลผู้ขาย)
- หน้ารายการที่ขายแล้ว/ปิดการขายแล้ว (ราคาซื้อขายจริงและวันที่)
- โปรไฟล์ผู้ขายและรีวิว
Python เป็นภาษาที่เหมาะกับงานนี้มากที่สุด เพราะ ecosystem ของมัน — Requests, BeautifulSoup, lxml, pandas — ช่วยให้ดึงหน้าเว็บ วิเคราะห์ HTML และจัดการข้อมูลได้ง่าย แต่ก็ต้องแยกให้ออกระหว่างการสแครป HTML ของเว็บไซต์กับการใช้ eBay API อย่างเป็นทางการ ซึ่งผมจะอธิบายต่อไป
ทำไมต้องดึงข้อมูล eBay? ตัวอย่างการใช้งานจริงสำหรับทีมธุรกิจ
ถ้าคุณกำลังอ่านบทความนี้ คุณคงมีเหตุผลของตัวเองอยู่แล้ว แต่ก็อยากวางเรื่องนี้บนฐานของมูลค่าธุรกิจจริง ๆ เพราะ ROI ของข้อมูลจาก eBay นั้นน่าสนใจมาก Bain พบว่า การปรับราคาให้ดีขึ้นเพียง 1% สามารถเพิ่มกำไรได้ 11.1% ในธุรกิจนับพันแห่ง ส่วน McKinsey ระบุว่า pricing แบบ dynamic ในค้าปลีกช่วยเพิ่มยอดขายได้ สูงสุด 5% และปรับ margin ดีขึ้น 2–7%
กรณีใช้งานที่เจอบ่อยที่สุด:
| Use Case | Data Needed | Business Outcome |
|---|---|---|
| ติดตามราคาและปรับราคาใหม่ | ราคาของรายการที่ยัง active, ค่าจัดส่ง, สภาพสินค้า | ตั้งราคาแข่งขันได้ ปกป้องกำไรขั้นต้น |
| วิเคราะห์คู่แข่ง | หมวดสินค้า โปรโมชัน เงื่อนไขการจัดส่ง | วางตำแหน่งทางการตลาดและหา assortment gap |
| วิจัยตลาดและจับเทรนด์ | ความถี่การลงขาย เทรนด์ในหมวดสินค้า รูปแบบความต้องการ | หาไอเดียสินค้าใหม่และคาดการณ์ดีมานด์ |
| ตั้งราคาสำหรับรีเซล / ประเมินมูลค่า | ราคาที่ขายได้จริง วันที่ขาย สภาพสินค้า | ประเมินมูลค่าตลาดอย่างเป็นธรรม ตัดสินใจ buy-box |
| วิเคราะห์ความรู้สึก | รีวิว คะแนน และนโยบายคืนสินค้า | มองเห็นคุณภาพสินค้าและความพึงพอใจลูกค้า |
| หาลีด | โปรไฟล์ผู้ขาย ข้อมูลร้าน รายละเอียดติดต่อ | เข้าถึงผู้ขาย B2B ที่มียอดขายรวมสูง |

แก่นของเรื่องคือ eBay มีข้อมูลอยู่จริง แต่ข้อมูลนั้นถูกขังไว้ในหน้าเว็บ
การสแครปคือวิธีเปลี่ยนข้อมูลนั้นให้กลายเป็นความได้เปรียบทางการแข่งขัน
eBay API อย่างเป็นทางการ vs การสแครปด้วย Python: ควรเลือกอะไร?
นี่เป็นคำถามที่ผมอยากให้คู่มือส่วนใหญ่ตอบอย่างตรงไปตรงมามากกว่านี้ eBay มี API อย่างเป็นทางการ — โดยเฉพาะ Browse API — และหลายคนสงสัยว่าควรใช้ API หรือดึงข้อมูลจากหน้าเว็บโดยตรง คำตอบขึ้นอยู่กับว่าคุณต้องการข้อมูลแบบไหน
| Criteria | eBay Browse/Finding API | Python Web Scraping |
|---|---|---|
| รายการที่ขายแล้ว/ปิดการขายแล้ว | จำกัด — มี Marketplace Insights API แต่ มักถูกปฏิเสธสิทธิ์เข้าถึง | เข้าถึงได้เต็มผ่านพารามิเตอร์ URL LH_Sold=1&LH_Complete=1 |
| ขีดจำกัดการเรียกใช้งาน | 5,000 calls/day ในระดับพื้นฐาน | จัดการเอง (ขึ้นอยู่กับ proxy) |
| ฟิลด์ข้อมูล | กำหนดมาแล้วล่วงหน้า (ชื่อ ราคา หมวดสินค้า ข้อมูลผู้ขายพื้นฐาน) | ทุกอย่างที่เห็นบนหน้าเว็บ (รีวิว สเปกเต็ม ตารางตัวเลือกสินค้า) |
| ความซับซ้อนในการตั้งค่า | OAuth 2.0, ลงทะเบียนแอป, API keys | ติดตั้งด้วย pip + เขียนโค้ด |
| ความเสถียร | ปลายทางเสถียร | พังเมื่อ HTML เปลี่ยน |
| ค่าใช้จ่าย | มีแบบใช้ฟรี และมีค่าใช้จ่ายเมื่อใช้งานปริมาณสูง | โค้ดใช้ฟรี แต่ต้องจ่ายค่า proxy เมื่อสเกลใหญ่ |
| ข้อมูลตัวแปร/MSKU | ได้บางส่วน — หลายกรณีได้แค่ parent SKU | ได้ครบ (ผ่านการอ่าน JSON ที่ซ่อนอยู่) |
| ความลึกของการแบ่งหน้า | เพดานแข็งที่ 10,000 รายการ | ในทางทฤษฎีไม่จำกัด |
หมายเหตุสั้น ๆ: Finding API แบบเก่า (ที่มี findCompletedItems) ถูก ยกเลิกใช้งานทั้งหมดในเดือนกุมภาพันธ์ 2025 แล้ว ถ้าคุณใช้ ebaysdk-python หรือไลบรารีใดก็ตามที่เรียก Finding module อยู่ ตอนนี้มันใช้จริงใน production ไม่ได้แล้ว
คำแนะนำของผม: ใช้ Browse API สำหรับข้อมูลแคตตาล็อกที่ต้องการความเสถียร ปริมาณไม่สูงมาก และเป็นข้อมูลแบบมีโครงสร้างบนรายการที่ยัง active อยู่ ส่วน Python scraping เหมาะเมื่อคุณต้องการราคาที่ขายแล้ว รีวิว ข้อมูลตัวเลือกสินค้า หรือฟิลด์ใดก็ตามที่ API ไม่เปิดให้ใช้ หลายทีมใช้ทั้งสองวิธีร่วมกัน
เครื่องมือและไลบรารีที่ต้องใช้ในการดึงข้อมูล eBay ด้วย Python
ก่อนจะเขียนโค้ด มาดูชุดเครื่องมือกันก่อน คุณไม่จำเป็นต้องใช้ headless browser สำหรับหน้า eBay ส่วนใหญ่ เพราะข้อมูลมักฝังอยู่ใน HTML ที่เซิร์ฟเวอร์ส่งมาแล้ว
| Library | Purpose |
|---|---|
requests หรือ httpx | HTTP client สำหรับดาวน์โหลดหน้า eBay |
curl_cffi | HTTP client ที่เลียนแบบ TLS fingerprint ของเบราว์เซอร์จริง (สำคัญมากสำหรับข้าม Akamai) |
beautifulsoup4 | ตัวแยก HTML สำหรับดึงข้อมูลด้วย CSS selector |
lxml | Parser backend ที่เร็วสำหรับ BeautifulSoup |
jmespath | ภาษาสำหรับ query JSON ที่ซ้อนกันหลายชั้น |
pandas | จัดการข้อมูลและส่งออก CSV/Excel |
gspread | เชื่อมกับ Google Sheets |
ติดตั้งทั้งหมดได้ในบรรทัดเดียว:
pip install requests httpx curl_cffi beautifulsoup4 lxml jmespath pandas gspread
แนะนำให้ใช้ Python 3.11+ — เพราะ pandas 3.0 ต้องการ 3.10 ขึ้นไป และ 3.11 ยังช่วยเพิ่มความเร็วงานที่เน้น I/O ได้ราว 10–60%
มีหนึ่งไลบรารีที่ควรพูดถึงเป็นพิเศษ: curl_cffi คือการอัปเกรดที่ส่งผลมากที่สุดสำหรับ eBay scraper ในปี 2026 eBay ใช้ Akamai Bot Manager และตัวตรวจจับหลักของ Akamai คือ TLS fingerprinting ถ้าใช้ requests ธรรมดา จะส่ง JA3 fingerprint ที่ดูเป็น Python ทันทีและถูกจับได้ curl_cffi จะปลอม handshake ให้เหมือน Chrome จริง ซึ่งช่วยผ่านเป้าหมายที่มี Akamai ป้องกันได้ราว 90% โดยไม่ต้องพึ่ง headless browser
ลองใช้ Thunderbit กับทุกเว็บไซต์
ทีละขั้นตอน: วิธีดึงผลการค้นหา eBay ด้วย Python
นี่คือบทเรียนหลัก เราจะดึงรายการสินค้าจากหน้าผลการค้นหาของ eBay
- ระดับความยาก: มือใหม่ถึงระดับกลาง
- เวลาที่ต้องใช้: ประมาณ 30 นาทีสำหรับรอบแรกที่ใช้งานได้จริง
- สิ่งที่ต้องมี: Python 3.11+, ไลบรารีข้างต้น, terminal และ URL ผลการค้นหา eBay เป้าหมาย
ขั้นตอนที่ 1: ตั้งค่าโปรเจกต์ Python ของคุณ
สร้างโฟลเดอร์โปรเจกต์และติดตั้ง dependencies:
mkdir ebay-scraper && cd ebay-scraper
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install requests curl_cffi beautifulsoup4 lxml pandas
สร้างไฟล์ชื่อ scrape_ebay.py นี่จะเป็นพื้นที่ทำงานของคุณ
ขั้นตอนที่ 2: สร้าง eBay Search URL
โครงสร้าง URL ของ eBay ค่อนข้างตรงไปตรงมา พารามิเตอร์สำคัญคือ _nkw (keyword):
import urllib.parse
keyword = "airpods pro"
base_url = "https://www.ebay.com/sch/i.html"
params = {
"_nkw": keyword,
"_ipg": "120", # items per page: 60, 120, หรือ 240 (240 อาจกระตุ้น bot flag)
"_pgn": "1", # เลขหน้า
}
url = f"{base_url}?{urllib.parse.urlencode(params)}"
print(url)
# https://www.ebay.com/sch/i.html?_nkw=airpods+pro&_ipg=120&_pgn=1
พารามิเตอร์ที่มีประโยชน์อื่น ๆ:
LH_BIN=1— เฉพาะ Buy It Now_sacat=175673— หมวดสินค้าระบุเจาะจง_sop=12— เรียงตาม best match (10 = ราคาพร้อมค่าส่งต่ำสุด, 13 = ลงขายล่าสุด)LH_Complete=1&LH_Sold=1— รายการที่ขายแล้ว/ปิดการขายแล้ว (จะกล่าวถึงในหัวข้อเฉพาะด้านล่าง)
ขั้นตอนที่ 3: ส่งคำขอและจัดการกับ response
ตรงนี้แหละที่ curl_cffi คุ้มค่า การใช้ requests.get() ธรรมดามักจะโดน Akamai ตอบกลับด้วย 403 แต่ถ้าใช้ curl_cffi เราจะปลอมตัวเป็น Chrome จริง:
from curl_cffi import requests as cffi_requests
import random, time
USER_AGENTS = [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0",
]
HEADERS = {
"User-Agent": random.choice(USER_AGENTS),
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
}
def fetch_page(url, max_retries=5):
delay = 2
for attempt in range(max_retries):
try:
r = cffi_requests.get(url, impersonate="chrome124", headers=HEADERS, timeout=30)
if r.status_code == 200:
return r.text
if r.status_code in (403, 429, 503):
retry_after = r.headers.get("Retry-After")
sleep_for = float(retry_after) if retry_after else delay + random.uniform(0, 1)
print(f" Status {r.status_code}, retrying in {sleep_for:.1f}s...")
time.sleep(sleep_for)
delay *= 2
continue
r.raise_for_status()
except Exception as e:
print(f" Request error: {e}, retrying...")
time.sleep(delay)
delay *= 2
raise RuntimeError(f"Failed after {max_retries} retries: {url}")
การ backoff แบบ exponential พร้อม jitter สำคัญมาก — การหน่วงเวลาคงที่เองก็เป็น fingerprint ของ bot เช่นกัน
ขั้นตอนที่ 4: แยกข้อมูลรายการสินค้าจากหน้าผลการค้นหา
eBay กำลังอยู่ระหว่างย้ายเลย์เอาต์ผลการค้นหาระหว่างสองแบบ ตอนนี้ scraper ที่ทนทานต้องรองรับทั้งคู่:
| Field | Legacy Layout | New Layout |
|---|---|---|
| คอนเทนเนอร์ของการ์ด | li.s-item | li.s-card หรือ div.su-card-container |
| ชื่อสินค้า | .s-item__title | .s-card__title |
| URL | a.s-item__link[href] | a.su-link[href] |
| ราคา | span.s-item__price | .s-card__price |
โค้ดแยกข้อมูลที่รองรับทั้งสองเลย์เอาต์:
from bs4 import BeautifulSoup
def parse_search_results(html):
soup = BeautifulSoup(html, "lxml")
cards = soup.select("li.s-item, li.s-card, div.su-card-container")
results = []
for card in cards:
# ชื่อสินค้า — ลองทั้งสอง layout
title_el = card.select_one(".s-item__title, .s-card__title")
title = title_el.get_text(strip=True) if title_el else None
# ข้ามการ์ดหลอก "Shop on eBay" ซึ่งเป็น placeholder
if not title or "Shop on eBay" in title:
continue
# ราคา
price_el = card.select_one("span.s-item__price, .s-card__price")
price = price_el.get_text(strip=True) if price_el else None
# URL
link_el = card.select_one("a.s-item__link[href], a.su-link[href]")
url = link_el["href"].split("?")[0] if link_el else None
# รูปภาพ
img_el = card.select_one("img.s-item__image-img, .s-card__image img")
image = None
if img_el:
image = img_el.get("src") or img_el.get("data-src")
# ค่าจัดส่ง
ship_el = card.select_one("span.s-item__shipping, span.s-item__logisticsCost, .s-card__attribute-row")
shipping = ship_el.get_text(strip=True) if ship_el else None
results.append({
"title": title,
"price": price,
"url": url,
"image": image,
"shipping": shipping,
})
return results
กับดัก card แรกที่เป็น placeholder เป็นเรื่องคลาสสิกมาก หลายหน้าค้นหาของ eBay จะมี li.s-item ตัวแรกเป็น placeholder ที่ซ่อนอยู่ ชื่อว่า "Shop on eBay" และไม่มีราคาจริง ต้องกรองทิ้งเสมอ
ขั้นตอนที่ 5: จัดการ pagination เพื่อดึงหลายหน้า
eBay ใช้พารามิเตอร์ _pgn สำหรับแบ่งหน้า ลิงก์ไปหน้าถัดไปใช้ a.pagination__next:
import urllib.parse
def scrape_ebay_search(keyword, max_pages=5):
all_results = []
for page_num in range(1, max_pages + 1):
params = {"_nkw": keyword, "_ipg": "120", "_pgn": str(page_num)}
url = f"https://www.ebay.com/sch/i.html?{urllib.parse.urlencode(params)}"
print(f"Scraping page {page_num}: {url}")
html = fetch_page(url)
results = parse_search_results(html)
if not results:
print(f" No results on page {page_num}, stopping.")
break
all_results.extend(results)
print(f" Found {len(results)} listings (total: {len(all_results)})")
# เว้นจังหวะสุภาพ — 3 ถึง 8 วินาทีแบบสุ่ม
time.sleep(random.uniform(3, 8))
return all_results
การหน่วงแบบสุ่ม 3–8 วินาทีไม่ใช่ตัวเลือกเสริม
eBay มีชั้น Akamai ที่จับได้เมื่อมีการยิงคำขอต่อเนื่องเกิน 1 req/s จาก IP เดียว
ขั้นตอนที่ 6: ส่งออกข้อมูลที่ดึงมาเป็น CSV หรือ JSON
import pandas as pd
results = scrape_ebay_search("airpods pro", max_pages=3)
df = pd.DataFrame(results)
df.to_csv("ebay_airpods.csv", index=False)
df.to_json("ebay_airpods.json", orient="records", indent=2)
print(f"Exported {len(df)} listings to CSV and JSON.")
ตอนนี้คุณควรได้สเปรดชีตที่สะอาดของรายการสินค้า eBay แล้ว บนเครื่องของผม การดึงข้อมูล 3 หน้า (360 listings) ใช้เวลาประมาณ 45 วินาทีรวม delay
วิธีดึงข้อมูลหน้ารายละเอียดสินค้าของ eBay ด้วย Python
หน้าค้นหาให้ข้อมูลสรุป แต่หน้ารายละเอียดสินค้ามีข้อมูลที่ลึกกว่า: คำอธิบายเต็ม คะแนน feedback ของผู้ขาย รายละเอียดเฉพาะรายการ และข้อมูลตัวเลือกสินค้า
แยกข้อมูลจากหน้าสินค้ารายการเดียว
หน้ารายการของ eBay อยู่ที่ /itm/<ITEM_ID> วิธีดึงข้อมูลที่เสถียรที่สุดคือ JSON-LD — eBay ฝังบล็อก schema แบบ Product ที่ทนต่อการเปลี่ยนแปลง CSS ได้แทบทุกครั้ง:
import json
def parse_item_page(html):
soup = BeautifulSoup(html, "lxml")
item = {}
# 1. JSON-LD — เส้นทางดึงข้อมูลที่เสถียรที่สุด
for tag in soup.find_all("script", type="application/ld+json"):
try:
data = json.loads(tag.string or "")
except (json.JSONDecodeError, TypeError):
continue
if isinstance(data, dict) and data.get("@type") == "Product":
item["title"] = data.get("name")
item["brand"] = (data.get("brand") or {}).get("name")
item["images"] = data.get("image")
offers = data.get("offers") or {}
item["price"] = offers.get("price")
item["currency"] = offers.get("priceCurrency")
break
# 2. CSS fallback สำหรับฟิลด์ที่ไม่มีใน JSON-LD
def first_text(selectors):
for sel in selectors:
el = soup.select_one(sel)
if el and el.get_text(strip=True):
return el.get_text(strip=True)
return None
item.setdefault("title", first_text([
"h1.x-item-title__mainTitle",
"h1.x-item-title__mainTitle .ux-textspans--BOLD",
]))
item["condition"] = first_text([
".x-item-condition-text .ux-textspans",
])
item["seller"] = first_text([
".x-sellercard-atf__info__about-seller a .ux-textspans",
])
item["shipping"] = first_text([
"div.ux-labels-values--shipping .ux-textspans--BOLD",
])
# 3. รายละเอียดเฉพาะรายการ
specifics = {}
for dl in soup.select(".ux-layout-section-evo__item--table-view dl.ux-labels-values"):
k = dl.select_one(".ux-labels-values__labels-content .ux-textspans")
v = dl.select_one(".ux-labels-values__values-content .ux-textspans")
if k and v:
specifics[k.get_text(strip=True).rstrip(":")] = v.get_text(strip=True)
item["specifics"] = specifics
return item
แพตเทิร์นนี้ — ใช้ JSON-LD ก่อน แล้วค่อย fallback ไปที่ CSS — คือกุญแจสำคัญของการสร้าง scraper ที่ไม่พังทุกไตรมาส จะอธิบายเพิ่มต่อไปด้านล่าง
ดึงข้อมูลตัวเลือกสินค้า eBay (MSKU Data)
บางรายการของ eBay มีหลายตัวเลือก — สี ขนาด ความจุ หน้าจอที่เห็นจะโชว์แค่ช่วงราคาเช่น "$899 ถึง $1,099" จนกว่าผู้ใช้จะคลิกเลือก option จริง ราคาของแต่ละ variant ถูกเก็บอยู่ใน JavaScript object ที่ซ่อนอยู่ชื่อ MSKU
นี่เป็นจุดที่ eBay API ให้ข้อมูลได้แค่บางส่วน (parent SKU) ทำให้การสแครปเป็นทางเลือกที่ดีกว่า
import re, json
def extract_variants(html):
# ต้องใช้แบบ non-greedy — ถ้า greedy .+ จะกินทั้งหน้า
m = re.search(r'"MSKU"\s*:\s*(\{.+?\})\s*,\s*"QUANTITY"', html, re.DOTALL)
if not m:
return []
try:
msku = json.loads(m.group(1))
except json.JSONDecodeError:
return []
item_labels = {str(k): v["displayLabel"] for k, v in msku.get("menuItemMap", {}).items()}
skus = []
for combo_key, variation_id in msku.get("variationCombinations", {}).items():
option_ids = combo_key.split("_")
options = [item_labels.get(oid, oid) for oid in option_ids]
var = msku.get("variationsMap", {}).get(str(variation_id), {})
bin_model = var.get("binModel", {})
price_spans = bin_model.get("price", {}).get("textSpans", [{}])
price = price_spans[0].get("text") if price_spans else None
qty = var.get("quantity")
skus.append({
"options": options,
"price": price,
"quantity_available": qty,
"variation_id": variation_id,
})
return skus
regex แบบ non-greedy (.+?) ตรงนี้แหละที่ทำให้ scraper eBay พังกันบ่อยที่สุด ถ้าใช้ .+ แบบ greedy มันจะกวาดทุกอย่างจนถึง "QUANTITY" ตัวสุดท้ายในหน้า ทำให้ได้ JSON ที่เสียรูปแบบ ผมเห็นบั๊กนี้ในบทความ "ใช้งานได้จริง" มาหลายชิ้นแล้วอย่างน้อยสามบท
วิธีดึงรายการ eBay ที่ขายแล้วและปิดการขายแล้วด้วย Python
นี่คือ use case ที่ทำให้การสแครปคุ้มกว่า API ข้อมูลสินค้าที่ขายไปแล้ว — ขายได้จริงราคาเท่าไร วันที่ไหน — คือมาตรฐานทองคำสำหรับงานวิจัยตลาด การตั้งราคาใหม่ และการประเมินมูลค่า Browse API ของ eBay ไม่ได้ให้ข้อมูลนี้โดยตรง แม้ว่า Marketplace Insights API จะให้ได้ในทางทฤษฎี แต่การเข้าถึงอยู่ในรูปแบบ "Limited Release" และ มักถูกปฏิเสธ
พารามิเตอร์ URL ที่คุณต้องใช้คือ LH_Complete=1 (รายการที่ปิดการขายแล้ว) และ LH_Sold=1 (เฉพาะที่ขายได้จริง) คุณต้องใส่ทั้งสองตัว ถ้าใส่แค่ LH_Sold=1 อย่างเดียว ในบางหมวด eBay จะย้อนกลับไปแสดงรายการ active แบบเงียบ ๆ — นี่คือกับดักที่คนในชุมชนพลาดกันบ่อยที่สุด
def scrape_sold_listings(keyword, max_pages=3):
all_sold = []
for page_num in range(1, max_pages + 1):
params = {
"_nkw": keyword,
"_ipg": "120",
"_pgn": str(page_num),
"LH_Complete": "1",
"LH_Sold": "1",
}
url = f"https://www.ebay.com/sch/i.html?{urllib.parse.urlencode(params)}"
print(f"Scraping sold page {page_num}...")
html = fetch_page(url)
soup = BeautifulSoup(html, "lxml")
cards = soup.select("li.s-item")
for card in cards:
title_el = card.select_one(".s-item__title")
title = title_el.get_text(strip=True) if title_el else None
if not title or "Shop on eBay" in title:
continue
# เอาเฉพาะรายการที่ขายจริง (ราคาเขียวใน .POSITIVE)
sold_tag = card.select_one(
".s-item__title--tag .POSITIVE, .s-item__caption--signal.POSITIVE"
)
if sold_tag is None:
continue # รายการที่ปิดแล้วแต่ยังขายไม่ออก — ข้าม
price_el = card.select_one("span.s-item__price")
price = price_el.get_text(strip=True) if price_el else None
# แยกวันที่ขาย
sold_date = None
import re, datetime as dt
card_text = card.get_text()
m = re.search(r"Sold\s+([A-Z][a-z]{2}\s+\d{1,2},\s*\d{4})", card_text)
if m:
sold_date = dt.datetime.strptime(m.group(1), "%b %d, %Y").strftime("%Y-%m-%d")
link_el = card.select_one("a.s-item__link[href]")
url = link_el["href"].split("?")[0] if link_el else None
all_sold.append({
"title": title,
"sold_price": price,
"sold_date": sold_date,
"url": url,
})
if not cards:
break
time.sleep(random.uniform(3, 8))
return all_sold
ความต่างสำคัญใน HTML คือ รายการที่ขายแล้วจะแสดงราคาเป็นสีเขียว (อยู่ใน wrapper .POSITIVE) ส่วนรายการที่ปิดแล้วแต่ขายไม่ออกจะเป็นสีแดงขีดฆ่า ต้องกรองด้วยคลาส .POSITIVE เสมอ
ทำไม eBay scraper ถึงพังบ่อย และจะสร้างตัวที่ทนทานได้อย่างไร
ถ้า scraper ของคุณหยุดทำงาน คุณไม่ได้เจอปัญหาคนเดียว นี่คือ pain point อันดับหนึ่งในทุกกระทู้เรื่อง eBay scraping ที่ผมเคยอ่าน คำถามไม่ใช่ว่า scraper จะพังไหม แต่เป็นว่า จะพังเมื่อไร
สาเหตุที่เกิดขึ้น:
- eBay ใช้การ render แบบ React กับชื่อคลาสที่สร้างแบบไดนามิกและเปลี่ยนไปตามรอบ deploy
- A/B test ส่ง DOM structure ต่างกันให้ผู้ใช้ต่างกลุ่ม (เลย์เอาต์ dual
s-item/s-cardเป็นตัวอย่างจริงตอนนี้) - การปรับดีไซน์เว็บไซต์เป็นระยะทำให้โครง HTML เปลี่ยน แม้ข้อมูลจะเหมือนเดิม
- selector เก่าอย่าง
#itemTitleและ#prcIsumถูกถอดออกไปหลายปีแล้ว แต่ยังโผล่อยู่ในบทความสอนจำนวนมาก
อย่างที่ คู่มือปี 2026 ของ Scrapfly บอกไว้ว่า: "ความท้าทายจริงของการสแครป eBay คือการรับมือกับการเปลี่ยนแปลง CSS selector ของ eBay พวกเขาอัปเดต frontend เป็นประจำ ทำให้ scraper ที่พึ่งชื่อคลาสเฉพาะพังได้ง่าย"

กลยุทธ์ป้องกันสำหรับ eBay scraper ที่ใช้งานได้นาน
สี่แนวทางที่ช่วยให้รอดจากการเปลี่ยนหน้าเว็บของ eBay ในแต่ละไตรมาส:
1. ให้ความสำคัญกับ JSON-LD มากกว่า CSS selector eBay ฝัง structured data แบบ Product ไว้ในทุกหน้ารายการ ข้อมูลชั้นนี้เปลี่ยนช้ากว่าชั้นการแสดงผลมาก — นักออกแบบอาจรีแฟกเตอร์ CSS ทุกไตรมาส แต่ฟิลด์ backend อย่าง price, name, และ seller มักแมปกับ internal API และแทบไม่เปลี่ยนชื่อ
2. ใช้ selector แบบ fallback ต่อเนื่อง อย่าพึ่ง CSS selector ตัวเดียว ให้เตรียมตัวเลือกสำรองเสมอ:
def first_text(soup, selectors):
for sel in selectors:
el = soup.select_one(sel)
if el and el.get_text(strip=True):
return el.get_text(strip=True)
return None
title = first_text(soup, [
"h1.x-item-title__mainTitle",
"h1.x-item-title__mainTitle .ux-textspans--BOLD",
"[data-testid='x-item-title'] h1",
])
3. อ่าน JSON blob ที่ซ่อนอยู่ อ็อบเจ็กต์ variant แบบ MSKU และข้อมูล JavaScript แบบ inline มักอยู่รอดจากการเปลี่ยน CSS เพราะถูกสร้างจากฝั่งเซิร์ฟเวอร์ การใช้ regex ดึงจาก <script> อาจต้องทำงานเพิ่มตั้งแต่แรก แต่ช่วยลดภาระดูแลระยะยาวได้มาก
4. บันทึก selector ที่ล้มเหลว ใส่ monitoring เพื่อให้รู้ว่า selector เริ่มใช้ไม่ได้เมื่อไร ไม่ใช่แค่รู้ว่าข้อมูลว่าง:
if title is None:
print(f"WARNING: title selector failed for {url}")
5. ใช้ curl_cffi พร้อม browser impersonation วิธีนี้ช่วยรับมือ TLS fingerprinting ของ Akamai โดยไม่ต้องใช้ headless browser
ทางเลือกที่ขับเคลื่อนด้วย AI: ไม่ต้องดูแล selector เอง
ถ้าคุณเบื่อการแก้ selector ทุกไม่กี่เดือน มีแนวทางที่ต่างออกไปอย่างสิ้นเชิง เครื่องมืออย่าง Thunderbit ใช้ AI อ่านหน้าเว็บใหม่ทุกครั้งและสร้างตรรกะการดึงข้อมูลให้แบบอัตโนมัติ งานวิจัยจาก McGill University ทดสอบ scraper แบบ AI เทียบกับ scraper แบบ selector บน 3,000 หน้า และพบว่า วิธี AI ยังแม่นยำได้ถึง 98.4% แม้ layout จะเปลี่ยนไป ขณะที่ benchmark ในอุตสาหกรรมระบุว่าสามารถ ลดงานบำรุงรักษา scraper ได้ 60–80%
| Approach | Breaks when eBay changes HTML? | Maintenance effort |
|---|---|---|
| Hardcoded CSS selectors | ใช่ ทุกไตรมาส | สูง — ต้อง patch ตลอด |
| Hidden JSON / JSON-LD extraction | แทบไม่ค่อยพัง | ต่ำ |
| AI-based scraping (Thunderbit) | ไม่ — AI สร้าง selector ใหม่ทุกครั้ง | ไม่มี |
ดึงข้อมูล eBay ด้วย AI Get Started Free
ผมจะอธิบาย workflow ของ Thunderbit แบบละเอียดในภายหลัง แต่ประเด็นตอนนี้คือ ถ้าคุณกำลังสร้าง scraper ที่จะรันต่อเนื่องเป็นเดือน ๆ ควรลงทุนกับการดึงข้อมูลจาก JSON ก่อน แล้วค่อยมี fallback selector ถ้าคุณไม่อยากดูแล selector เองเลย แนวทาง AI ก็น่าสนใจมาก
ทำให้การดึงข้อมูล eBay เป็นงานอัตโนมัติสำหรับการติดตามราคา
การสแครปครั้งเดียวมีประโยชน์ แต่การติดตามราคา สต็อก และคู่แข่งต้องใช้การเก็บข้อมูลแบบ ทำซ้ำเป็นรอบ ๆ บทความคู่แข่งเกือบทุกชิ้นพูดถึง use case เรื่องติดตามราคา แต่มีน้อยมากที่โชว์วิธีทำให้เป็นอัตโนมัติจริง
ตัวเลือกที่ 1: Cron Jobs (Linux/macOS) หรือ Task Scheduler (Windows)
วิธีที่ง่ายที่สุดคือห่อสคริปต์ Python ของคุณไว้ใน cron job เสมอให้ใช้ path เต็มของ Python ใน venv เพราะ cron ทำงานใน environment ที่มีตัวแปรน้อยมาก:
crontab -e
# ทุกวันเวลา 08:15
15 8 * * * /Users/me/ebay/venv/bin/python /Users/me/ebay/scrape_ebay.py >> /Users/me/ebay/scrape.log 2>&1
บน Windows ใช้ PowerShell:
$A = New-ScheduledTaskAction -Execute "C:\Users\me\ebay\venv\Scripts\python.exe" -Argument "C:\Users\me\ebay\scrape_ebay.py"
$T = New-ScheduledTaskTrigger -Daily -At 8:15am
Register-ScheduledTask -TaskName "eBayScraper" -Action $A -Trigger $T
วิธีนี้ต้องมีเครื่องที่เปิดไว้ตลอด และคุณต้องดูแล proxy กับมาตรการกันบอทเอง
ตัวเลือกที่ 2: Cloud Functions (Serverless)
AWS Lambda หรือ Google Cloud Functions ช่วยให้รัน scraper ได้โดยไม่ต้องมีเซิร์ฟเวอร์เฉพาะของตัวเอง ติดตั้งยากกว่า — ต้องแพ็ก dependencies, จัดการ timeout (Lambda จำกัด 15 นาที) และยังต้องดูแล proxy เอง แต่ข้อดีคือไม่ต้องดูแลเซิร์ฟเวอร์
ตัวเลือกที่ 3: ตั้งเวลาแบบไม่ต้องเขียนโค้ดด้วย Thunderbit
ฟีเจอร์ Scheduled Scraper ของ Thunderbit ให้คุณบอกช่วงเวลาด้วยภาษาธรรมดา เช่น "ทุกวันตอน 8 โมงเช้า" ใส่ URL ของ eBay แล้วกด Schedule ระบบจะรันบนคลาวด์พร้อมการจัดการ anti-bot ในตัว
| Approach | Setup Effort | Needs Server? | Handles Anti-Bot? |
|---|---|---|---|
| Cron + Python script | ปานกลาง | ใช่ (เครื่องต้องเปิดตลอด) | คุณต้องจัดการ proxy เอง |
| Cloud function (Lambda) | สูง | ไม่ต้อง (serverless) | คุณต้องจัดการ proxy เอง |
| Thunderbit Scheduled Scraper | ต่ำ (อธิบายเป็นคำพูด) | ไม่ต้อง (ทำงานบนคลาวด์) | มีในตัว |
ถ้าจะเก็บข้อมูลที่สแครปซ้ำ ๆ ฐานข้อมูล SQLite ในเครื่องถือเป็นคำตอบที่เหมาะสำหรับ history ของราคา ใช้ ON CONFLICT ... DO UPDATE แทน INSERT OR REPLACE เพราะแบบหลัง ทำให้ foreign key พังและลบค่าบางคอลัมน์
CREATE TABLE IF NOT EXISTS listings (
item_id TEXT PRIMARY KEY,
title TEXT NOT NULL,
price REAL,
last_price REAL,
first_seen_at TEXT DEFAULT (datetime('now')),
last_seen_at TEXT DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS price_history (
item_id TEXT NOT NULL,
observed_at TEXT NOT NULL DEFAULT (datetime('now')),
price REAL NOT NULL,
PRIMARY KEY (item_id, observed_at)
);
ลองใช้ Thunderbit Scheduled Scraper
ไม่อยากเขียนโค้ด? วิธีดึงข้อมูล eBay ภายใน 2 นาทีด้วย Thunderbit
ผมใช้ไปแล้วกว่า 2,000 คำกับโค้ด Python ตอนนี้อยากพูดอย่างตรงไปตรงมาว่าบางครั้งคุณไม่ต้องใช้มันเลย
ถ้าคุณเป็นผู้ใช้ธุรกิจที่ทำวิจัยตลาดแบบครั้งเดียว, พ่อค้ารีเซลที่ต้องเทียบสินค้า, หรือทีม ecommerce ที่ต้องการข้อมูล ตอนนี้ โดยไม่ต้องรอรอบพัฒนา Python อาจเกินความจำเป็น การตั้งค่า การดูแล selector การจัดการ proxy — ทั้งหมดนี้เป็น overhead จำนวนมากสำหรับงานที่แค่ "ต้องการ 200 รายการลงสเปรดชีต"
Thunderbit ดึงข้อมูล eBay อย่างไร (ทีละขั้นตอน)
- ติดตั้ง Thunderbit Chrome Extension — ไม่ต้องใช้บัตรเครดิต
- เปิดหน้า search results หรือหน้าสินค้าของ eBay ใน Chrome
- คลิก "AI Suggest Fields" ในแถบด้านข้างของ Thunderbit AI จะอ่านหน้าและเสนอคอลัมน์ เช่น Title, Price, Condition, Shipping, Seller, Rating
- คลิก "Scrape" ส่วนขยายจะไล่หน้าถัดไปให้อัตโนมัติและกรอกตารางข้อมูล สำหรับ eBay โดยเฉพาะ Thunderbit มี เทมเพลต scraper สำเร็จรูป ที่ใช้ได้ด้วยคลิกเดียว
- Export ไปยัง Google Sheets, Airtable, Notion, CSV, JSON หรือ Excel — ฟรี
กระบวนการทั้งหมดใช้เวลาไม่ถึง 2 นาที
ผมจับเวลาไว้แล้ว
เพิ่มข้อมูลจากหน้ารายละเอียดโดยไม่ต้องเขียนโค้ดเพิ่ม
หลังจากดึงข้อมูลจากหน้าผลการค้นหาแล้ว Thunderbit ยังสามารถเข้าไปที่หน้ารายละเอียดของแต่ละรายการและเพิ่มฟิลด์อื่น ๆ ได้ เช่น สเปกเต็ม ข้อมูลผู้ขาย คำอธิบาย และรูปภาพทั้งหมด ซึ่งแทนโค้ด Python สำหรับดึง subpage กว่า 20 บรรทัดที่เราเขียนไปก่อนหน้าด้วยการคลิกเพียงครั้งเดียว
เมื่อไรยังควรใช้ Python
Python เหมาะกว่าเมื่อคุณต้องการ:
- สแครปปริมาณใหญ่ (หลักหมื่นหน้าต่อรอบ)
- ตรรกะการแยกข้อมูลหรือแปลงข้อมูลที่ปรับแต่งลึกมาก
- เชื่อมกับ data pipeline ที่มีอยู่แล้ว (Airflow, dbt, Kafka)
- ควบคุม TLS/session แบบละเอียด สำหรับงานกันบอทขั้นสูง
- ต้นทุนต่อหน่วยที่คำนวณได้ชัด — เมื่อระดับข้อมูลเป็นล้านแถว สแตกที่ดูแลเองมักคุ้มกว่า SaaS แบบคิดเครดิต
สำหรับโปรเจกต์ครั้งคราวหรือระดับกลาง Thunderbit เร็วและง่ายกว่า แต่ถ้าเป็น pipeline ระดับ production ที่สเกลใหญ่ Python จะให้คุณควบคุมได้เต็มที่
เคล็ดลับหลีกเลี่ยงการถูกบล็อกเมื่อดึงข้อมูล eBay ด้วย Python
aKamai ของ eBay เอาอยู่จริงในโลกงานภาคสนาม สิ่งที่ใช้ได้จริงคือ:
- ใช้
curl_cffiพร้อมimpersonate="chrome124"— เป็นการอัปเกรดที่เห็นผลชัดที่สุดเมื่อเทียบกับrequestsธรรมดา - หมุน User-Agent จากรายชื่อเบราว์เซอร์เวอร์ชันปัจจุบัน (Chrome 143, Firefox 124, Safari 26)
- ใส่ delay แบบสุ่ม ระหว่างคำขอ 3–8 วินาที — จังหวะคงที่คือ fingerprint
- ใช้ residential proxy หรือ rotating proxy สำหรับงานที่เกินไม่กี่สิบหน้า IP จากดาต้าเซ็นเตอร์ (AWS, GCP, DigitalOcean) จะถูก Akamai จับได้เร็วมาก
- เคารพ
robots.txt— URL browse ส่วนใหญ่ถูก Disallow ไว้อย่างชัดเจน; แต่หน้ารายละเอียดสินค้า (/itm/<id>) ไม่ได้ถูกห้าม - จัดการ CAPTCHA อย่างสุภาพ — ตรวจจับแล้วลองใหม่ด้วย IP อื่น หรือใช้บริการแก้ CAPTCHA
- อย่ายิงถี่เกินไป คดี eBay v. Bidder's Edge แสดงให้เห็นว่าการสแครปที่ทำให้เซิร์ฟเวอร์เสียหายอาจเข้าข่าย trespass to chattels การอยู่ที่ประมาณ 1 req/s ต่อ IP จะปลอดภัยกว่านั้นมาก
ถ้าใช้ในเชิงพาณิชย์และปริมาณสูง แนะนำให้ใช้ Browse API สำหรับรายการ active และใช้การสแครปเฉพาะจุดกับข้อมูล sold comps และฟิลด์ที่ API ไม่เปิด วิธีแบบผสมนี้สะอาดทั้งด้านเทคนิคและกฎหมายมากกว่า
การสแครป eBay ด้วย Python ถูกกฎหมายไหม?
ผมไม่ใช่ทนาย และบทความนี้ไม่ใช่คำปรึกษาทางกฎหมาย ดังนั้นขอสรุปแบบสั้น ๆ
ภูมิทัศน์ทางกฎหมายในปัจจุบันเอื้อต่อการสแครปข้อมูลที่เปิดสาธารณะ ประเด็นสำคัญคือ:
- hiQ v. LinkedIn (9th Cir., 2022): การสแครปข้อมูลที่เข้าถึงได้สาธารณะไม่ละเมิด CFAA
- Van Buren v. United States (SCOTUS, 2021): ตีความข้อ "exceeds authorized access" ของ CFAA แคบลง
- Meta v. Bright Data (N.D. Cal., 2024): การสแครปขณะล็อกเอาต์ไม่ได้ละเมิด TOS ของแพลตฟอร์มเพราะ scraper ไม่ใช่ "user"
อย่างไรก็ตาม ข้อตกลงผู้ใช้ของ eBay ที่ อัปเดตเมื่อกุมภาพันธ์ 2026 ระบุชัดว่าห้าม "buy-for-me agents, LLM-driven bots, หรือกระบวนการ end-to-end ใด ๆ ที่พยายามสั่งซื้อโดยไม่มีมนุษย์ตรวจสอบ" เส้นแบ่งชัดเจน: การอ่านข้อมูลหน้าเว็บสาธารณะอย่างเดียวถือว่าอยู่บนพื้นฐานที่แข็งแรง แต่การทำ checkout อัตโนมัติไม่ใช่
แนวปฏิบัติที่ดีคือดึงเฉพาะข้อมูลที่มองเห็นได้สาธารณะ ไม่สร้างบัญชีปลอม ไม่ข้ามกำแพงล็อกอิน และไม่เอารูปภาพในรายการที่มีลิขสิทธิ์ไปขายต่อทั้งชุด และถ้าเป็นโปรเจกต์เชิงพาณิชย์ในระดับใหญ่ ควรปรึกษาผู้เชี่ยวชาญด้านกฎหมาย
บทสรุปและข้อคิดสำคัญ
Python เป็นวิธีที่ยืดหยุ่นที่สุดสำหรับการดึงข้อมูล eBay แต่ก็ต้องดูแลต่อเนื่องเมื่อ HTML ของเว็บไซต์เปลี่ยนไป กรอบการตัดสินใจคือ:
- ใช้ eBay Browse API สำหรับการ query แบบเสถียร ปริมาณไม่สูงมาก และเป็นข้อมูลแบบมีโครงสร้างบนรายการ active
- ใช้ Python scraping สำหรับรายการที่ขายแล้ว รีวิว ข้อมูลตัวเลือกสินค้า และฟิลด์ใดก็ตามที่ API ไม่เปิด
- ใช้ Thunderbit ถ้าคุณอยากได้ข้อมูล eBay โดยไม่ต้องเขียนหรือดูแลโค้ด
โค้ดในคู่มือนี้เน้นความทนทาน: ดึง JSON-LD ก่อน, ตามด้วย CSS fallback หลายชั้น, และอ่าน JSON ที่ซ่อนอยู่สำหรับ variants แนวทางเป็นชั้น ๆ แบบนี้ช่วยให้ scraper ของคุณไม่ล้มทันทีเมื่อทีม frontend ของ eBay ปล่อย redesign ใหม่
ถ้าคุณอยากลองทางไม่ต้องเขียนโค้ด แผนใช้ฟรีของ Thunderbit ให้คุณทดสอบบนหน้า eBay ได้ทันที และถ้าอยากดูว่า เทมเพลต eBay scraper ทำงานอย่างไร ก็ลองคลิกเดียวได้เลย
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเครื่องมือ web scraping ดูคู่มือของเราเรื่อง เครื่องมือ web scraping อัตโนมัติที่ดีที่สุด, ดึงข้อมูลจากเว็บไซต์ไปยัง Excel, และ เครื่องมือ Python web scraping ที่ดีที่สุด คุณยังสามารถดูวิดีโอสอนที่ Thunderbit YouTube Channel
ลองใช้ Thunderbit สำหรับการดึงข้อมูล eBay Get Started Free
คำถามที่พบบ่อย
1. ฉันสามารถดึงข้อมูล eBay ฟรีด้วย Python ได้ไหม?
ได้ ไลบรารีทั้งหมด (Requests, BeautifulSoup, curl_cffi, pandas) เป็นฟรีและ open source ค่าใช้จ่ายจะเกิดเมื่อสเกลใหญ่ — residential proxies สำหรับการสแครปปริมาณสูงมักอยู่ที่ประมาณ 50–500 ดอลลาร์ต่อเดือน ขึ้นอยู่กับแบนด์วิดท์ สำหรับโปรเจกต์เล็ก ๆ (ไม่กี่ร้อยหน้า) คุณสามารถใช้ IP บ้านของตัวเองได้ ถ้าจัด rate limit อย่างระมัดระวัง
2. จะดึงรายการที่ขายแล้วและปิดการขายแล้วของ eBay ด้วย Python อย่างไร?
เพิ่ม LH_Complete=1&LH_Sold=1 ในพารามิเตอร์ URL ของ search คุณต้องใส่ทั้งคู่ — ถ้าใส่แค่ LH_Sold=1 ในบางหมวด eBay จะย้อนกลับไปแสดงรายการ active แบบเงียบ ๆ กรองผลลัพธ์โดยตรวจคลาส CSS .POSITIVE บนองค์ประกอบราคา เพราะนี่คือสัญญาณว่ามีการขายจริง ไม่ใช่รายการที่หมดอายุแต่ขายไม่ออก
3. eBay บล็อกการสแครปเว็บไหม?
eBay ใช้ Akamai Bot Manager ซึ่งตรวจจับ scraper หลัก ๆ ผ่าน TLS fingerprinting และ behavioral analysis การเรียกด้วย requests ธรรมดามักได้ 403 การใช้ curl_cffi ร่วมกับ browser impersonation, การหมุน User-Agent และ delay สุ่ม 3–8 วินาทีระหว่างคำขอ ช่วยผ่านการบล็อกส่วนใหญ่ได้ โปรฯ ที่สเกลใหญ่ควรใช้ residential proxies
4. ควรใช้ eBay API หรือ web scraping ดี?
ใช้ Browse API สำหรับ query ที่เสถียรและปริมาณไม่สูงมากบนรายการ active (ได้ถึง 5,000 calls/day) ใช้การสแครปเมื่อคุณต้องการประวัติราคาที่ขายแล้ว, ข้อมูล MSKU/variants แบบครบ, รีวิว หรือฟิลด์ใดก็ตามที่ API ไม่เปิดให้ใช้ Marketplace Insights API มีข้อมูล sold ได้จริง แต่การเข้าถึงถูกจำกัดและ มักถูกปฏิเสธ
5. วิธีที่ง่ายที่สุดในการดึงข้อมูล eBay โดยไม่เขียนโค้ดคืออะไร?
Thunderbit Chrome extension ใช้ AI อ่านหน้า eBay แนะนำคอลัมน์ข้อมูล และดึงรายการด้วยการคลิกครั้งเดียว รองรับการไล่หน้าถัดไป การเพิ่มข้อมูลจาก subpage และ export ไปยัง Google Sheets, Excel, Airtable หรือ Notion เทมเพลต eBay scraper ที่สร้างไว้ล่วงหน้าช่วยให้ใช้งานกับเคสยอดนิยมได้เร็วขึ้นอีก
เรียนรู้เพิ่มเติม


