eBay Product Scraper
Under maintenancePricing
from $5.00 / 1,000 scraped product results
eBay Product Scraper
Under maintenanceFast, reliable eBay scraper. Extract product search results, pricing, shipping, seller specs, item condition & high-res images to JSON/Excel. No API key needed.
Pricing
from $5.00 / 1,000 scraped product results
Rating
0.0
(0)
Developer
Elena Vance
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
an hour ago
Last modified
Categories
Share
Extract eBay listings — price, shipping, condition, seller rating, item specifics, images and descriptions — from keyword searches or direct listing URLs. No eBay API key, no login.
Results are stored in an Apify dataset you can export as JSON, CSV, Excel, XML or HTML.
What makes this scraper reliable
eBay does not simply return 403 when it does not like a request. It answers with a bot challenge page carrying a 200 OK status — a page that looks perfectly valid to a naive scraper and parses to zero rows. That is the single most common reason an eBay scraper "succeeds" while returning nothing.
This Actor is built around that reality:
- Every response is screened before parsing. Challenge pages, eBay's branded error shell and blocked status codes all retire the current session and retry on a fresh proxy IP and browser fingerprint.
- A page that loads but parses to nothing is treated as a failure, not as an empty result — unless eBay's own "no matches found" copy is on the page. Silent zero-row runs are impossible by construction.
- The two ways of scraping nothing are told apart. A run where no page could be loaded fails with an actionable message; a search that genuinely has no matches succeeds and says so. Neither one finishes green with an unexplained empty dataset.
- Both generations of eBay's markup are supported. eBay replaced the long-standing
s-itemsearch layout withs-card; the extractor reads either.
Adaptive crawling: fast when it can be, resilient when it must be
A browser is expensive — memory, time, and on residential proxies, bandwidth. Plain HTTP is roughly an order of magnitude cheaper, but eBay blocks it from some IP pools.
Rather than guessing, the Actor spends one probe request at startup to find out which transport eBay accepts for this run:
| Result | What happens |
|---|---|
| Probe succeeds | Runs on the fast HTTP crawler. Anything that later gets blocked is automatically retried in a real browser. |
| Probe is blocked | Runs on the Playwright browser crawler, which executes the challenge JavaScript. |
In browser mode, images, fonts, media and analytics are blocked before they are fetched, which cuts proxy bandwidth several-fold without losing any scraped data.
You can override the decision with Crawler mode (auto / http / browser).
Consistent, comparable rows
Two details that quietly ruin an eBay dataset are handled for you:
- Proxy country is pinned to the marketplace. eBay quotes prices, shipping and currency in the requesting IP's locale, so an unpinned residential pool returns rows priced in whatever countries the proxies happened to land in. Searching
ebay.depins the pool to Germany unless you choose a country yourself. - The list layout is requested explicitly. Above 60 results per page eBay switches to a gallery card that silently drops seller name, feedback, watch and sold counts. The Actor forces the list layout at every page size, so those fields are present whether you ask for 10 items or 10,000.
Input
Provide a search keyword, start URLs, or both.
| Field | Type | Default | Description |
|---|---|---|---|
search | array of strings | – | Keywords to search, e.g. ["macbook pro m3"]. Each is crawled separately. |
startUrls | array | – | eBay search-results URLs or listing (/itm/...) URLs. Non-eBay URLs are rejected. |
ebaySite | string | ebay.com | Marketplace for keyword searches. 18 regional sites supported. |
maxItems | integer | 2 | Hard cap on stored products. The run stops as soon as it is reached. |
maxPagesPerQuery | integer | 5 | Pagination depth per search. |
scrapeDetails | boolean | true | Open each listing page for specifics, galleries, returns and description. |
scrapeDescription | boolean | true | Fetch the seller's description iframe (one extra request per listing). |
includeDescriptionHtml | boolean | false | Also store the description as raw HTML. |
sortBy | string | bestMatch | bestMatch, lowestPrice, highestPrice, newlyListed, endingSoonest. |
itemCondition | string | all | all, new, refurbished, used. |
listingType | string | all | all, buyItNow, auction. |
proxyConfiguration | object | Apify Proxy, RESIDENTIAL | Residential proxies are strongly recommended. |
crawlerMode | string | auto | auto, http, browser. |
maxConcurrency | integer | 10 | Upper bound on parallel requests. |
maxRequestRetries | integer | 5 | Retries per request, each on a fresh identity. |
debugSnapshots | boolean | false | Save page HTML to the key-value store when extraction fails. |
Example input
{"search": ["macbook pro m3"],"ebaySite": "ebay.com","maxItems": 200,"scrapeDetails": true,"itemCondition": "used","sortBy": "lowestPrice","proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
Speed vs. depth
scrapeDetails: false is not a stripped-down mode — the search page alone already yields price, original price, shipping, condition, buying format, seller name and feedback, item location, watch counts and the main image. It costs one request per 60–240 listings instead of one per listing, so it is dramatically faster and cheaper. Turn details on when you need item specifics, full image galleries, variations, return policy or descriptions.
Pricing
This Actor is pay per event — you pay only for what a run actually does, not for compute time:
| Event | Price | When it's charged |
|---|---|---|
| Actor Start | $0.02 | Once per run (scales with memory: 1 event per GB, minimum 1) |
| Scraped Product Result | $0.003 | Once per listing saved to the dataset |
Worked example: a default run (2048 MB, maxItems: 2) costs 2 × $0.02 for the start event, plus up to 2 × $0.003 for results — around $0.07. Turning off scrapeDetails doesn't change the per-result price, but it finishes faster and uses less proxy bandwidth per item.
maxItems scales the cost linearly — a 100-item run costs about $0.34, a 20-item run about $0.10. These two events are the entire cost of a run — there's no separate platform/compute charge on top. See the Pricing tab on this Actor's page for the current, canonical numbers.
Output
One dataset row per listing:
{"itemId": "307090982870","url": "https://www.ebay.com/itm/307090982870","title": "Apple MacBook Pro 16\" (512GB SSD, M3 Pro, 18GB) Space Black","subtitle": "Brand New · 16 in · 512 GB","condition": "Brand New","price": 1849.26,"priceText": "$1,849.26","currency": "USD","originalPrice": null,"shipping": 279.46,"shippingText": "+$279.46 shipping estimate","freeShipping": false,"buyingFormat": "Best Offer","itemLocation": "United Kingdom","watchers": 13,"soldCount": null,"seller": { "name": "reece_c94", "feedbackPercent": 100, "feedbackScore": 136 },"brand": "Apple","mpn": "MRW13LL/A","specifics": { "Brand": "Apple", "Screen Size": "16 in", "Processor": "M3 Pro" },"images": ["https://i.ebayimg.com/images/g/VxsAAeSwYelqaEGZ/s-l1600.webp"],"variations": [],"returnPolicy": "30 days returns. Buyer pays for return shipping.","availability": "More than 10 available","descriptionText": "…","isSponsored": true,"scrapedAt": "2026-08-18T09:12:44.481Z"}
Notable fields:
price/currency— parsed from the marketplace's own locale format, so1.249,99onebay.deand1,249.99onebay.comboth become1249.99.shipping—0for free shipping,nullwhen eBay does not state a cost (never silently guessed as0).isSponsored— eBay renders a reversed, transparent decoy label on every card; this field resolves the realaria-labelledbytarget, so it flags only genuine paid placements.url— canonicalised tohttps://<marketplace>/itm/<id>, with tracking parameters stripped, so the same listing is never scraped twice.seller.feedbackScore— locale-aware:4.286on ebay.de and143.4Kon ebay.com both resolve to a plain integer.
Requests that fail after all retries are written to a separate failed-requests dataset, keeping the main dataset free of error rows.
Troubleshooting
"Scraped 0 items — no page could be loaded"
eBay is rejecting the IP pool. Enable Apify Proxy with the RESIDENTIAL group, try a different proxy country, and lower maxConcurrency.
"eBay returned no listings for this input" The pages loaded fine and eBay genuinely had no matches, so the run succeeds with an empty dataset rather than failing. Check the keyword, the marketplace and the condition/listing-type filters.
Fewer items than maxItems
The search had fewer matches, maxPagesPerQuery capped the crawl, or some listings ended mid-run. Raise maxPagesPerQuery if the search itself had more results.
"…markup may have changed"
eBay altered its HTML. Re-run with debugSnapshots: true; the offending page is stored in the key-value store, which is exactly what a bug report needs.
A field I set doesn't seem to be applied
An out-of-range number or an unrecognized value (a typo in sortBy, crawlerMode, ebaySite, etc.) does not fail the run — it falls back to that field's default and logs a warning explaining what was ignored and why. Check the run log for a line starting with "Falling back to defaults for...".
Development
npm installnpm test # 104 unit + integration tests, no network requiredapify run --purge # local run; reads storage/key_value_stores/default/INPUT.json
Tests run against a fixture captured from a live eBay results page, so a markup change breaks the suite rather than the production run.
Legal
This Actor collects data that eBay publishes publicly, without logging in. You are responsible for using the scraped data in line with eBay's terms and the laws that apply to you — in particular, do not collect or process personal data without a lawful basis.