---
title: "How to Scrape eBay Listings (2026 Guide) | Scrape.ly"
description: "How to scrape eBay listings by keyword or URL: price, condition, seller, sold count and shipping, with a real run, its cost and code for curl and Python."
url: https://scrape.ly/blog/how-to-scrape-ebay
markdown: https://scrape.ly/blog/how-to-scrape-ebay.md
---

[Tutorials](https://scrape.ly/blog/category/tutorials.md)

# How to Scrape eBay: Listings, Prices, Conditions and Sold Counts

Scrape eBay listings by keyword or URL and get title, price, condition, seller, sold count, shipping and identifiers as rows, with eBay's bot check handled for you. A real run, its cost, and code for curl, Python and Node.js.

[Shelfbright Actor publisher on the Scrape.ly Store](https://scrape.ly/blog/author/shelfbright.md)

- Published

  Oct 23, 2026

- Reading time

  8 min read

![Pixel-art robot with an orange >\_ on its terminal head pulls a listing card with a photo and price off an auction board topped with the eBay logo and drops it into a crate](https://scrape.ly/media/how-to-scrape-ebay.png?w=1080)

Here is how to scrape eBay in one sentence: send a keyword or a search URL to a scraper that reads eBay's public search results and saves each active listing with its title, price, condition, seller, sold count, item location and shipping. The fastest way to do it is the eBay Scraper on Scrape.ly, which clears eBay's bot check for you and returns clean rows at $4 per 1,000 listings, with no eBay account, API key or proxy of your own.

This guide covers the no-code steps, the API (curl, Python, Node.js and AI agents over MCP), the cost and the pitfalls. Everything below comes from a real run on 22 October 2026: mechanical keyboards between $50 and $150, with the exact input, output, log and charge.

## What data you can get from eBay

The [eBay Scraper](https://scrape.ly/store/shelfbright/ebay-scraper.md) writes one row per active listing. These are the fields you'll use most:

| Field                                                                     | What it holds                                                                     |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `title`, `subTitle`                                                       | Listing title and subtitle                                                        |
| `price`, `priceWithCurrency`                                              | Current price as a number, and as eBay shows it ("US $74.00 or Best Offer")       |
| `wasPrice`, `wasPriceWithCurrency`                                        | The previous price, when eBay shows one                                           |
| `condition`                                                               | eBay's real condition label: `Brand New`, `Open Box`, `Certified - Refurbished` … |
| `sold`, `available`, `availableText`                                      | How many have sold, quantity left, and eBay's text for both                       |
| `seller`                                                                  | The seller's eBay name                                                            |
| `shippingCost`, `shippingCostWithCurrency`, `shipsTo`, `excludesShipping` | Shipping price and destinations                                                   |
| `itemLocation`                                                            | Where the item is located, as eBay shows it                                       |
| `brand`, `type`, `upc`, `ean`, `mpn`                                      | Product attributes and identifiers, when listed                                   |
| `categories`                                                              | eBay's category path                                                              |
| `image`, `images`                                                         | Main photo and all photos                                                         |
| `url`, `itemNumber`                                                       | Listing link and eBay item number                                                 |

Fields appear when eBay shows them for that listing, so `upc` or `wasPrice` can be empty. The Actor collects active listings only: sold and completed search URLs are skipped, but every row carries the item's sold count.

## How to scrape eBay listings without code

1. Open the [Actor's page](https://scrape.ly/store/shelfbright/ebay-scraper.md) in the Scrape.ly Store.
2. Pick a ready-made input. We used the preset [Mechanical keyboards 50-150 USD, 10 listings](https://scrape.ly/store/shelfbright/ebay-scraper/presets/keyword-price-filter.md). "Try this input" opens it in the console.
3. Change the keyword and price bounds to yours. This is the exact input of our run:

```json
{
  "keyword": "mechanical keyboard",
  "minPrice": 50,
  "maxPrice": 150,
  "maxItems": 10
}
```

4. Click **Start**. Expect 20 to 30 seconds for 10 listings: most of that is eBay's bot check, which the Actor solves itself.
5. Export the listings as JSON, CSV or Excel.

The fields that matter most:

- `keyword`: what you'd type into eBay's search box. Active listings only.
- `startUrls`: search, category or listing URLs, such as the preset [Cables from a search URL, 8 listings](https://scrape.ly/store/shelfbright/ebay-scraper/presets/search-url.md). Category pages work as search URLs (`/sch/...` with a category ID). The keyword runs first, then each URL.
- `maxItems`: listings to save for the whole run (default 10), counted across the keyword and all URLs.
- `minPrice`, `maxPrice`: price bounds in the site's currency. For a keyword, eBay applies them; for pasted URLs, the Actor filters after reading the page.

Scrape.ly Store eBay Scraper Active eBay listings by keyword or URL: price, condition, seller, sold count, shipping, UPC and photos. eBay's bot check is handled for you. $4 per 1,000 listings.

[Try it free](https://scrape.ly/store/shelfbright/ebay-scraper.md) [Browse the Store](https://scrape.ly/store.md)

## How to scrape eBay with the API

Create an API token under **Settings → API & Integrations** and export it as `SCRAPELY_TOKEN`.

Our run took 35 seconds because of the bot check, which is close to the 45-second limit of the synchronous endpoint. Use the asynchronous flow: start the run, wait, then read the items.

```shell
# 1. start the run; the response's data.id is the run ID
curl -X POST "https://api.scrape.ly/v2/actors/shelfbright~ebay-scraper/runs"
  -H "Authorization: Bearer $SCRAPELY_TOKEN"
  -H "Content-Type: application/json"
  -d '{"keyword": "mechanical keyboard", "minPrice": 50, "maxPrice": 150, "maxItems": 10}'
# 2. wait (up to 60 s per call; repeat until status is SUCCEEDED)
curl "https://api.scrape.ly/v2/actor-runs/RUN_ID?waitForFinish=60"
  -H "Authorization: Bearer $SCRAPELY_TOKEN"
# 3. read the listings (CSV here)
curl "https://api.scrape.ly/v2/actor-runs/RUN_ID/dataset/items?format=csv"
  -H "Authorization: Bearer $SCRAPELY_TOKEN"
```

Python (`pip install scrapely-client-python`). `call()` waits however long the run takes; this example ranks listings by price including shipping:

```python
import os
from scrapely_client import ScrapelyClient

client = ScrapelyClient(os.environ["SCRAPELY_TOKEN"], api_url="https://api.scrape.ly")

run = client.actor("shelfbright/ebay-scraper").call(
    run_input={"keyword": "mechanical keyboard", "minPrice": 50, "maxPrice": 150, "maxItems": 10}
)
print(run.status)  # SUCCEEDED, FAILED, ABORTED or TIMED-OUT
listings = list(client.dataset(run.default_dataset_id).iterate_items())
for item in sorted(listings, key=lambda i: i["price"] + (i.get("shippingCost") or 0)):
    total = item["price"] + (item.get("shippingCost") or 0)
    print(f'{total:7.2f}  {item["condition"]:24}  sold {item.get("sold") or 0:>3}  {item["title"][:50]}')
```

Node.js (`npm install scrapely-client`):

```javascript
import { ScrapelyClient } from 'scrapely-client';

const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN, baseUrl: 'https://api.scrape.ly' });

const run = await client.actor('shelfbright/ebay-scraper').call({
  keyword: 'mechanical keyboard',
  minPrice: 50,
  maxPrice: 150,
  maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.priceWithCurrency, i.condition, i.sold, i.url]));
```

For AI agents, add the Scrape.ly MCP server. In Cursor, put this in `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "scrapely": {
      "url": "https://api.scrape.ly/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}
```

In Claude Code, run `claude mcp add --transport http scrapely https://api.scrape.ly/mcp` and sign in with `/mcp`. Then ask: "Use scrapely to run shelfbright/ebay-scraper for 'mechanical keyboard' between $50 and $150, 10 listings, and give me a table of price, condition and sold count." Because the run takes more than 45 seconds at larger sizes, the agent polls `get-actor-run` and then reads the rows. The [eBay API](https://scrape.ly/api/ebay-api.md) page shows the same Actor as an API product, and the [Actors API docs](https://scrape.ly/docs/api-actors.md) list every endpoint.

## A real run: mechanical keyboards from $50 to $150

We ran the "Mechanical keyboards 50-150 USD, 10 listings" preset on 22 October 2026. It returned 10 listings in 35 seconds and was charged $0.0466. The first five rows:

| Listing                                                                     | Price                   | Condition               | Seller      | Sold | Shipping  |
| --------------------------------------------------------------------------- | ----------------------- | ----------------------- | ----------- | ---- | --------- |
| Redragon K550 RGB Gaming Keyboard, 104 Keys + 12 Macro G Keys Wired         | US $74.00 or Best Offer | Open Box                | \[seller 1] | 64   | Free      |
| Logitech MX Mechanical Mini Wireless TKL Keyboard Tactile Quiet Switches    | US $109.99              | Certified - Refurbished | \[seller 2] | 19   | Free      |
| Logitech K845ch Mechanical Illuminated Keyboard Cherry MX Blue New In Box   | US $75.00 or Best Offer | Brand New               | \[seller 3] | 2    | US $10.00 |
| Logitech G PRO X TKL Wireless Gaming Keyboard – Tactile Switches            | US $129.99              | Certified - Refurbished | \[seller 2] | 25   | Free      |
| Corsair K65 PLUS Wireless 75% RGB Hot-Swap Gaming Keyboard Certified Refurb | US $55.45               | Certified - Refurbished | \[seller 4] | 45   | Free      |

eBay sellers can be private individuals, so we show seller names as `[seller 1]` to `[seller 4]`; `[seller 2]` listed two of the five keyboards. What the full ten show:

- **The price filter held.** All 10 prices sat between $55.45 and $129.99.
- **Condition matters as much as price.** Five of ten were "Certified - Refurbished", two "Open Box", two "Brand New" and one "Excellent - Refurbished". Compare like with like before you call something cheap.
- **Shipping changes the ranking.** Eight of ten shipped free; the other two added $10.00 and $8.29.
- **Demand is visible.** The listings had sold 369 units between them, from 2 to 75 each. Four were open to a Best Offer.
- **Identifiers come along.** Nine of ten had a UPC and seven an MPN, which is what you need to match the same product across sellers or retailers.

The log, without the platform's start-up lines:

```plaintext
20261022T18:26:22.284Z [Scrapely] Container started (setup 1.0 s)
20261022T18:26:23.495Z [scrapely.actor] INFO  Antibot solver source: platform.
20261022T18:26:45.959Z [scrapely.actor] INFO  Reading 10 listings (10 found so far).
20261022T18:26:55.779Z [scrapely.actor] INFO  Saved 10 listings. Challenge solves: 4
20261022T18:26:56.408Z [Scrapely] Container state: status=exited exitCode=0 oomKilled=false
```

The 22 seconds between start and "Reading 10 listings" is eBay's bot check. The Actor solved four challenges with the platform's own solver, on the default datacenter proxy. You don't configure anything for it.

## What it costs

The Actor charges one event, $0.004 per listing saved, which is $4.00 per 1,000 listings. Platform usage (compute and proxy) is billed on top.

For our run: 10 listings × $0.004 = $0.04 in listing fees. The run was charged $0.0466 in total, because it also used $0.0047 of compute (the bot check is most of the run time), $0.0019 of datacenter proxy traffic and $0.00005 of dataset writes. A 1,000-listing job costs $4.00 in listing fees; a keyword or URL that matches nothing saves no rows and pays no listing fee.

## What to watch out for when scraping eBay

- **Active listings only.** Sold and completed searches are skipped. Use `sold` on each active row to see demand, and run the same search on a schedule to watch prices move.
- **Use&#x20;**__`/sch/`__ **URLs.** `/b/` browse URLs can stay on eBay's challenge page. A search or category search URL (`/sch/...`) works.
- **Bot checks add time, not work.** A 10-listing run typically takes 20 to 30 seconds. If eBay keeps its check up, the Actor retries once from a new exit and then fails with a clear message instead of handing you an empty dataset.
- **Layouts change.** Hand-written scrapers break on eBay's markup: ScrapingBee's guide (updated 25 September 2026) parses `li.s-card` cards, while many older guides target `li.s-item`. With the Actor, you read `price` and `condition` fields, not CSS classes.
- **The limit is per run.** `maxItems` counts across the keyword and all URLs, and a search stops when eBay shows no more result pages.
- **Seller names.** Many sellers are individuals. Store seller names only if you need them, and treat them as personal data.

## Is it legal to scrape eBay?

The Actor reads public listing pages that anyone can open without an account, and it never logs in or buys anything. Listing prices, titles and conditions are factual product data. eBay's User Agreement still sets rules for how its site may be accessed and used, so read the current version before you build a product on eBay data, and keep your request volume reasonable.

Privacy law applies to the people behind listings. A private seller's name and location are personal data under the GDPR and the CCPA. Collect only the fields you need, keep them secure, and have a lawful basis for processing them. This is not legal advice: if eBay data drives a commercial product, ask a lawyer about your case.

## Why Scrape.ly for eBay scraping

- **The bot check is solved for you.** Top tutorials add premium proxies, mobile user agents and retry logic to get past eBay's defenses. The Actor ships with the solver and the proxy, as the log above shows.
- **Rows instead of selectors.** Bright Data's Python tutorial walks through nine steps for one product page. Here a keyword returns structured rows with condition, sold count, shipping and UPC.
- **Predictable cost.** $4.00 per 1,000 listings plus small usage, and a maximum charge per run if you want a hard cap.
- **Built for monitoring.** Schedule the same search daily, send rows to Google Sheets or a webhook, and compare prices across Amazon, Walmart and Google Shopping, as in our [price scraping](https://scrape.ly/blog/price-scraping.md) guide.

## FAQ

### Can you scrape eBay without getting blocked?

Yes. The Actor clears eBay's bot check itself and uses a built-in datacenter proxy, so you don't need your own proxies or solver. In our run it solved four challenges and saved all ten listings.

### Can you scrape eBay sold listings?

The Actor returns active listings; sold and completed search URLs are skipped. Each active row includes how many units have sold (`sold`), which shows demand without leaving the live market.

### How do I scrape eBay listings with Python?

Install `scrapely-client-python`, call `shelfbright/ebay-scraper` with a keyword or URLs, and iterate over the dataset, as in the example above. The client waits for the run, including the bot check.

### Can I scrape a specific eBay category?

Yes. Paste the category's search URL (`/sch/...` with the category ID) into `startUrls`. Category pages are read like search URLs, and price bounds are applied after the page is read.

### How much does it cost to scrape eBay?

$0.004 per listing, so $4.00 per 1,000, plus a little compute and proxy usage. Our 10-listing run was charged $0.0466. The Free plan's $5 of monthly credit covers over 1,000 listings in listing fees.

Scrape.ly Store Scrape eBay listings Run the mechanical keyboards preset as-is, or type your own keyword or paste an eBay search URL. $4 per 1,000 active listings.

[Try it free](https://scrape.ly/store/shelfbright/ebay-scraper.md) [Browse the Store](https://scrape.ly/store.md)

About the author

[Shelfbright](https://scrape.ly/blog/author/shelfbright.md) Actor publisher on the Scrape.ly Store

Prices, stock and seller data from shops and marketplaces, from Amazon and AliExpress to Vinted and Leboncoin. For price trackers, catalogue teams and resellers. A Scrapely studio.

- [Website](https://scrape.ly/users/shelfbright.md)

Keep reading

## More in Tutorials

- [![Pixel-art robot with an orange >\_ on its terminal head pulls a review card with five gold stars out of a stack of cardboard boxes marked with the Amazon logo](https://scrape.ly/media/scrape-amazon-reviews.png?w=750)](https://scrape.ly/blog/scrape-amazon-reviews.md)
  ### [Amazon Review Scraping: How to Scrape Amazon Reviews Without a Login](https://scrape.ly/blog/scrape-amazon-reviews.md)
  [Amazon review scraping without an account: paste product URLs and get star ratings, titles, text, dates, countries and verified-purchase flags as rows. A real run, its exact cost, the limits to plan for, and code for curl, Python and Node.js.](https://scrape.ly/blog/scrape-amazon-reviews.md)
- [![Pixel-art robot with an orange >\_ on its terminal head pulls a post card out of a phone whose feed is topped by the white X logo and drops it into a crate](https://scrape.ly/media/scrape-twitter.png?w=750)](https://scrape.ly/blog/scrape-twitter.md)
  ### [How to Scrape Twitter (X): Tweets, Likes, Reposts and Replies](https://scrape.ly/blog/scrape-twitter.md)
  [Scrape Twitter (X) posts from any public profile, tweet URL or search, with no code or one API call. A real run on NASA's account, its output, its log and its exact cost, plus how it compares to the X API's per-post price.](https://scrape.ly/blog/scrape-twitter.md)
- [![Pixel-art robot with an orange >\_ on its terminal head pulls an article page out of a newspaper vending box topped with the Google News logo and drops it into a crate](https://scrape.ly/media/how-to-scrape-news-articles.png?w=750)](https://scrape.ly/blog/how-to-scrape-news-articles.md)
  ### [How to Scrape News Articles: Headlines, Full Text and Dates](https://scrape.ly/blog/how-to-scrape-news-articles.md)
  [Web scraping news takes two steps: find the headlines for a topic, then extract each article's text, author and publish date. Both steps with ready-made scrapers, two real runs with their exact cost, Python code, and the copyright rules.](https://scrape.ly/blog/how-to-scrape-news-articles.md)

## The internet is full of data. Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

[Get Started Free](https://my.scrape.ly/register) [Chat with Support](mailto:support@scrape.ly?subject=Question%20about%20Scrape.ly\&body=Hi%2C%20I%20have%20a%20question%20about%20Scrape.ly.)

No credit card. No setup calls.
