eBay Scraper — Search, Listings, Prices & Sellers
Pricing
$3.00 / 1,000 listing rows
eBay Scraper — Search, Listings, Prices & Sellers
eBay search results and item pages as structured rows: price, list price, shipping, condition, buying format, bids, units sold, watchers, seller feedback and location. Filter by price server-side across 11 marketplaces. Pay per listing row.
Pricing
$3.00 / 1,000 listing rows
Rating
0.0
(0)
Developer
Tedj MEABIOU
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Share
An eBay scraper that turns search results and item pages into clean rows: price, struck-through list price, shipping cost, condition, buying format, bids and time left, units sold, watchers, seller feedback score and percentage, item location and image. No API key, no login, no browser. It reads the same public pages a shopper sees, on 18 marketplaces, and bills you per listing row it actually delivers. Use it for ebay price research, for bulk ebay product data, and as an ebay api alternative when the official Browse API's onboarding is more than your project needs.
The differentiator is the demand column. Most ebay listing scraper output tells you what sellers are asking. This one also tells you what shoppers are doing about it: how many units a listing has already sold, how many people are watching it, how many bids an auction has drawn and how long it has left, whether the seller takes offers, and how far the current price sits below the seller's own list price. Those five numbers are what separate a price you can copy from a price nobody pays.
Last verified working: 2026-08-29.
eBay listings: what does this scraper collect?
Every row carries the same columns, whether it came from a search card or an item page, so exports are never ragged.
| Field | What it is |
|---|---|
item_id | eBay's numeric listing id — the number in any /itm/ URL |
title | Listing title as the seller wrote it |
url | Canonical item page URL |
query / search_url | The keyword, and the exact URL the page was read from |
page / position | Where the listing sat in eBay's own order, counted across pages |
domain / marketplace | com, co.uk, de … and the country name |
price / price_display / currency | The number, the string exactly as printed, and the currency read from the price itself. price is null on the occasional MAP-restricted listing where eBay prints "See price" instead of a number — price_display then says so, and price bounds drop those rows free |
list_price / list_price_display / discount_pct | The struck-through original and how far below it the listing sits |
shipping_cost / shipping_display / free_shipping | Delivery charge as a number, the full line, and the free-delivery flag |
condition | Brand New, Pre-Owned, Open Box, Certified - Refurbished, For parts … |
buying_format | buy_it_now or auction |
bids / time_left | Auction rows: bid count and eBay's own countdown text |
best_offer | Whether the seller accepts offers |
units_sold | How many units this listing has sold |
watchers | How many shoppers are watching it |
returns | The returns line, e.g. "Free returns" or "30 days returns" |
seller / seller_feedback_pct / seller_feedback_count | Username or store, positive-feedback percentage, and the score expanded from eBay's 40.6K shorthand to 40600 |
location | Where the item ships from |
image | Listing image URL |
rating / ratings_count | Product star rating, when the listing is matched to a catalogue product |
results_total | How many listings eBay reports for the whole search |
quantity_available, breadcrumbs, category, item_specifics, seller_url | Item-page rows only: availability text, the category path, the leaf category, the seller's specifics table, and the store URL |
fetched_at | UTC timestamp |
A second row type, status, is emitted once per keyword or URL and is always free: kind, target, status (ok / no_results / error), items, filtered, duplicates, pages, results_total, error, fetched_at. Read it to know that a job ran and what it produced, without inferring anything from row counts.
eBay search results by keyword: how do I get them?
To scrape eBay search results by keyword, give it keywords and a depth. Each page carries 60 listings.
{"queries": ["mechanical keyboard", "keycap set"],"domain": "com","pages": 2,"maxResultsPerQuery": 60}
That run reads two pages per keyword, keeps the first 60 listings of each in eBay's own order, and charges for 120 rows at most — fewer if a keyword returns fewer.
How do I use my own eBay search URL?
Build the search in a browser with whatever filters you like, copy the address bar into startUrls, and the actor reads it exactly as pasted. The marketplace comes from the URL, so one run can mix countries.
{"startUrls": ["https://www.ebay.co.uk/sch/i.html?_nkw=lego+star+wars&_sacat=19006","https://www.ebay.de/sch/i.html?_nkw=nintendo+switch+oled"],"pages": 3}
Individual item URLs work in the same field and return the richer item-page row — category breadcrumb, the seller's specifics table, availability and returns:
{"startUrls": ["https://www.ebay.com/itm/800459096845"]}
How does the price filter save me money?
minPrice and maxPrice become eBay's own _udlo and _udhi parameters, so eBay does the filtering before it sends the page. You pay for the pages that come back, not for thousands of rows you throw away afterwards. The bound is then checked a second time here, because eBay applies its own bound to price plus shipping in some views and a row can still arrive outside your range — anything that fails the second check is dropped and never billed. Those drops show up in the filtered count on the status row.
{"queries": ["vintage pocket watch"],"minPrice": 50,"maxPrice": 400,"buyingFormat": "auction","sortBy": "ending_soonest","pages": 2}
buyingFormat, conditions, category and sortBy are server-side in exactly the same way. conditions is a multi-select because eBay grades refurbished in four separate tiers — Certified, Excellent, Very good, Good — and a filter that sends only "refurbished" silently drops most of that market.
eBay price research: how do I compare a market?
Point the actor at a product's keywords, take the whole first page or two, and the distribution answers the question. This is bulk ebay data extraction with the analysis columns already attached. price plus shipping_cost is the real landed cost, and it is the number ebay buy it now shoppers actually compare. units_sold tells you which of those prices has ever transacted. The ebay units sold figure is the strongest signal on the page. The ebay watchers count tells you where interest sits without a sale yet, and a listing with many ebay watchers and no sales is usually priced above the market. results_total tells you how crowded the listing is. condition lets you split the used market from the new one, best_offer shows which sellers will negotiate — an ebay best offer flag on most of a page means the printed prices are ceilings, not clearing prices — and ebay seller feedback lets you discount the outliers from accounts nobody buys from.
A practical routine for resellers and sourcing teams:
- Run the keyword with
sortBy: "price_low"andpages: 2to find the floor. - Run it again with
buyingFormat: "auction"andsortBy: "ending_soonest"to see what is clearing right now. That is ebay auction data in its most useful form:bidsandtime_lefton those rows are live competition, and a lot of bids with little time left is a price about to be proved. - Sort your export by
units_solddescending. The top rows are the listings that have proven the price. - Compare
priceagainstlist_price— a largediscount_pctacross many sellers is a category in decline, not a bargain. - Schedule the same run daily and diff on
item_idto watch new listings, price moves andunits_soldgrowth.
This is the ebay market research loop that ebay reseller tools charge a monthly subscription for, except it lands in your own dataset and you pay by the row.
eBay seller data: how do I find who dominates a category?
The sellers view groups the same rows by who is selling. seller_feedback_count is expanded from eBay's abbreviated card display, so 40.6K becomes 40600 and you can sort on it numerically. Combined with units_sold, location and condition, this ebay seller feedback view is enough to find the handful of accounts that dominate a category, to check whether they are stores or private sellers, and to see how their pricing differs from the long tail. Auction cards are the one exception: eBay does not print the seller line on an auction card, so those rows carry the seller from the item page only.
eBay marketplaces: which ones are supported?
com, de, fr, it, es, at, nl, pl, com.au, com.sg, com.my — eleven, each measured on 2026-08-29 returning a full 60-listing page on the first request. Set domain for keyword searches, or paste marketplace URLs into startUrls and mix as many as you like in one run.
Five hosts are deliberately not offered: eBay UK, Ireland, Canada, Switzerland and Hong Kong answered eBay's anti-bot challenge on 18 of 18 attempts, across datacentre and residential proxies, country-pinned and not, warm and cold — while Germany and Australia answered 5 of 5 on the same proxies in the same minute. eBay's posture there is per-host and outside our control, and listing them as supported would sell you a run that cannot finish. If you want to try one anyway, paste its URL into startUrls: the row will still be labelled and priced in the right currency, and a refusal comes back as a plain status: "error" rather than as an empty market. We re-check this on every release. Condition labels, buying-format wording and the shipping line are all parsed in each site's own language, so a German run returns Gebraucht and Sofort-Kaufen rather than nulls. currency is read from the rendered price rather than assumed from the marketplace, because eBay localises the price block to the caller's egress and a run proxied through another country would otherwise be labelled with the wrong currency.
How much does it cost?
Pay per event: $0.003 per listing row, and nothing else. There is no per-run start fee and no compute charge on top.
- A search that returns nothing is free.
- Listings where eBay withholds the price ("See price") are dropped free whenever you have set a price bound.
- Rows dropped by your price bounds are free.
- A listing found by two of your keywords is delivered and billed once per run.
statusrows are free.- If your spending limit is reached mid-run, the run stops delivering rather than delivering rows it could not charge for — you never receive unpaid data and never pay for data you did not receive.
One page of 60 listings is $0.18. A daily two-page watch on five keywords is about $1.80 a month.
Every input, explained
| Input | Default | What it does |
|---|---|---|
queries | [] | Keywords to search, one job each |
startUrls | [] | eBay search URLs read verbatim, and/or individual item URLs |
domain | com | Marketplace for the keyword searches (11 verified hosts) |
buyingFormat | all | all, buy_it_now or auction |
conditions | [] | Multi-select of the nine eBay condition grades |
minPrice | 0 | Lower bound, sent to eBay and re-checked before billing |
maxPrice | 0 | Upper bound; 0 means none |
category | "" | eBay numeric category id (the _sacat number in any category URL) |
sortBy | best_match | best_match, ending_soonest, newly_listed, price_low, price_high |
pages | 1 | Result pages per job, 60 listings each, up to 34 |
maxResultsPerQuery | 0 | Cap per job; 0 means everything the pages returned |
sessions | 4 | Parallel proxy sessions (egress IPs) |
perIp | 0.5 | Requests per second per IP |
proxyConfiguration | Apify Proxy | Required; the run escalates to residential on its own |
How do I call it from Python, JavaScript or curl?
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("kestrel/ebay-search-scraper").call(run_input={"queries": ["mechanical keyboard"],"pages": 2,"minPrice": 30,"maxPrice": 200,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["type"] == "item":print(row["price"], row["currency"], row["units_sold"], row["title"])
JavaScript (Node):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('kestrel/ebay-search-scraper').call({queries: ['keycap set'],pages: 1,sortBy: 'price_low',});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((r) => r.type === 'item').length, 'listings');
curl:
curl -X POST "https://api.apify.com/v2/acts/kestrel~ebay-search-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'content-type: application/json' \-d '{"queries":["vintage pocket watch"],"buyingFormat":"auction","pages":1}'
Does it work with n8n, Make and AI agents?
Yes. The actor is a standard Apify Actor, so it appears in the n8n Apify node and in Make's Apify app as "Run an Actor", and the dataset comes back as ordinary JSON you can map straight into a sheet, a database or an alert. For agents, the Apify MCP server exposes it as a callable tool, so an AI agent can ask for eBay listings by keyword and get typed rows back rather than a page of HTML. The status rows make it safe for an agent to run unattended: a failure is a row with status: "error" and a readable message, never a silently empty result.
Zapier, Airtable and Google Sheets all work through the same dataset endpoint, and the "Run Actor and get dataset" pattern needs no code.
eBay API alternative: why not use the official API?
The eBay Browse API is excellent if you are already an eBay developer: you register an application, complete the onboarding, manage OAuth tokens and live inside its rate limits and its field set. For a one-off market study, a price watch, a sourcing spreadsheet or an agent tool, that is a lot of ceremony. This actor is the ebay api alternative for those cases — paste keywords, get rows, pay for what you got. It also returns things the catalogue-shaped API does not surface the same way: the struck-through list price a seller is advertising against, the watcher count, the units already sold on that specific listing, and the exact position the listing held in eBay's own results.
If you need order management, listing creation, or guaranteed contractual access, use the official API. If you need to read the public market, use this.
Does this scraper collect eBay sold items?
No, and here is why. eBay's completed and sold search — the LH_Sold=1&LH_Complete=1 view — is behind a sign-in gate. A logged-out request to it is redirected to signin.ebay.<tld> with sgfl=srch, on every marketplace. We verified this on 2026-08-29 across seven marketplaces, datacentre and residential proxies in seven countries, eight different URL routes including eBay's own "Sold items" rail link and the RSS feed, and three browser fingerprints: not one of roughly 115 attempts returned sold results. A headless browser does not change the answer, because the block is an HTTP redirect and not a JavaScript challenge — only a signed-in eBay account gets through, which we will not do on your behalf or ours.
So this actor scrapes active listings only, and says so plainly rather than shipping a "sold" toggle that returns nothing. If you came here for ebay sold items to build price comps, the honest substitute is the units_sold column: it is the number of units a live listing has actually sold at its current price, published by eBay on the public results page, and for pricing decisions it answers most of the same question — has anyone paid this? — using data that is genuinely available.
FAQ
How many listings are on each eBay page?
Sixty. The actor requests _ipg=60, which is eBay's ceiling. pages: 3 therefore reads up to 180 listings per job. eBay stops paginating any single search at roughly 2000 items however many it reports in results_total, which is why pages is capped at 34.
Why did my search return no rows?
Either eBay genuinely found nothing, or the run was refused. The two are never confused: a genuine miss produces a status row with status: "no_results" and costs nothing, and a refusal produces status: "error" with the reason. This matters more than it sounds — eBay's zero-result page still renders about twenty "results matching fewer words" cards from other searches, and a scraper that delivers those bills you for listings you never asked for. This one drops them.
Do I need a proxy?
Yes, and Apify Proxy is the default. eBay is behind Akamai Bot Manager and refuses unrotated callers with a /splashui/challenge interstitial. The run opens several proxy sessions, warms each one against the marketplace homepage, paces every session separately, retries on a different IP whenever a page is refused, and escalates from datacentre to residential proxies by itself once eBay has pushed back twice. Measured at one request per second on 2026-08-29: datacentre answered 5 of 10 searches and residential 8 of 10, so with retries a run completes reliably on either.
Are sponsored listings flagged?
There is deliberately no sponsored column. eBay's current results page prints the (deliberately obfuscated) "Sponsored" disclosure on every card — 60 of 60 on four different searches across two marketplaces and both buying formats, all from the same organic results module. A column that is always true is worse than no column, so we left it out and documented the finding instead.
Can I track prices over time?
Yes — schedule the run and keep the datasets. Each row carries fetched_at, item_id and price, which is everything a time series needs. A daily run of the same keywords, appended to one table and grouped by item_id, gives you an ebay price tracker with the listing's units_sold and watchers moving alongside the price, which is far more informative than the price alone.
What about eBay Kleinanzeigen or eBay Motors?
Kleinanzeigen is a separate site with its own markup and is not covered. Motors listings are ordinary eBay listings and come back like any other, though vehicle-specific attributes live in item_specifics on item-page rows rather than in dedicated columns.
Is scraping eBay legal?
This actor reads only publicly available pages — the same search results and item pages any visitor sees without logging in — and collects no personal data beyond the seller usernames and store names eBay itself publishes next to every listing. Public-data scraping of this kind is broadly lawful in the US and the EU, and courts have repeatedly declined to treat access to a public web page as unauthorised access. That is not the whole story, though: eBay's own Terms of Service restrict automated access, so scraping can be a contractual matter between you and eBay even where it is not a legal one. You are responsible for your own use — respect robots directives and rate limits, do not republish listing content wholesale, keep collection proportionate to your purpose, and take your own legal advice for anything commercial. We do not scrape anything behind a login, and we will not: that is exactly why the sold-listings view above is absent rather than faked.
How do I find an eBay category id?
Open any eBay category in a browser and read the _sacat number out of the URL, or click into a category from a search and copy it from the address bar. Pass it as category and every keyword in the run is searched inside that category only.
Changelog and support
See CHANGELOG.md for version history. If a field stops populating, open an issue on the actor's Issues tab with the input you used — the parsers are covered by an offline test suite built from captured pages, and a fixture from a real failing run is the fastest possible fix.
Related scrapers
eBay is one marketplace. These read the others, with the same row-per-item shape and the same pay-per-delivered-row billing:
- Amazon Product Scraper — one ASIN in, the whole product page out: buybox and list price, stock flag, gallery, bullet points and the details table, across 20 marketplaces — the Amazon column of a price-spread table.
- Amazon Search Scraper — Amazon keyword results with page position and a sponsored flag, when you want to know what ranks for a phrase there the way this actor tells you for eBay.
- Amazon Best Sellers Scraper — the Top 100 of any Amazon category with every rank filled, plus New Releases, for demand ranking rather than price.
- Amazon Reviews Scraper — customer reviews and ratings by ASIN with filters that run before billing, for the feedback behind a listing you priced here.
- AliExpress Reviews Scraper — buyer feedback with photos, the variant chosen and the buyer's country, for checking a supplier's product before you list it on eBay.
All of them bill per delivered row, never charge for rows a filter or a spending limit removed, and write an Apify dataset you can export to CSV, Excel or JSON.