OmniScrape
ProductsSolutionsGuidesDocs ↗PricingAbout
ProductsSolutionsGuidesDocs ↗PricingAbout
← All guides
Site-Specific Scrapers

eBay Scraper: Extract Listings, Auctions, and Sold Prices

eBay is structurally different from fixed-retail catalogues. A single search result set can mix auction-format listings, Buy It Now fixed-price offers, Best Offer negotiations, and multi-variation parent items — each with a different DOM template. Listings expire, bid counts update in real time, and the same item number may resolve differently on ebay.com versus ebay.co.uk.

This guide covers the practical mechanics: which URL patterns are stable across redesigns, which CSS selectors reliably target price and seller data, how to handle bot detection on search versus item-view endpoints, and how to structure a pipeline that tracks both active listings and sold comps. For broader marketplace context, see ecommerce web scraping.

All code examples use the OmniScrape API with residential proxies. The Web Unlocker capability is engaged by setting enable_solver: true — no separate endpoint or mode name is needed.

On this page

1. eBay listing fields worth capturing2. eBay URL patterns by region and listing type3. eBay item page DOM structure and CSS selectors4. eBay bot detection: behavior and mitigation5. Scrape an active eBay listing6. Scrape sold listing search results7. Auction timing, bid tracking, and currency normalization8. Marketplace monitoring pipeline design9. eBay API, developer policies, and legal considerations10. FAQ

1.eBay listing fields worth capturing

The right field set depends on the use case. Resellers tracking arbitrage opportunities care about the spread between current bid and Buy It Now price. Brand protection teams need seller identity and unauthorized listing detection. Pricing analysts building valuation models need sold comps with condition and shipping normalized out.

Item specifics — the structured table of attributes like Storage Capacity, Color, or Compatible Model — are often more useful than free-text titles for product matching across listings. Capture them as a key-value map rather than a flat string.

Watchers count is a soft demand signal. eBay shows it on listings above a threshold; when absent, treat it as zero rather than null — the field is conditionally rendered, not always missing.

  • Item ID — numeric suffix from /itm/ URL, stable across edits
  • Title, subtitle (when present), and item specifics table as key-value pairs
  • Listing format: auction, Buy It Now, Best Offer, or combination
  • Current price or current bid amount with currency code
  • Bid count and auction end time (UTC-normalized)
  • Buy It Now price when auction and BIN coexist on the same listing
  • Shipping cost, carrier, and estimated delivery window
  • Condition label and seller-provided condition description
  • Seller username, feedback score (raw count), and positive feedback percentage
  • Quantity available and quantity sold for multi-unit fixed-price listings
  • Watchers count when rendered
  • Sold comps: final sale price, end date, and condition for completed listings

2.eBay URL patterns by region and listing type

Item view URLs — /itm/NUMERIC — are the most stable entry point and have survived multiple eBay front-end redesigns. Search and category browse pages carry heavier bot-detection pressure and are more likely to trigger challenges at volume.

Regional eBay TLDs share the same item ID namespace but maintain separate catalogs, seller accounts, and currency contexts. A proxy region should match the TLD you are targeting: use residential:uk for ebay.co.uk, residential:de for ebay.de. Mismatched proxy regions can trigger geo-redirect responses that return the wrong regional site.

Sold listing search is the primary source for comp data. The LH_Sold=1&LH_Complete=1 parameter combination filters to completed, sold listings only. LH_Complete=1 alone includes unsold completed listings — useful for sell-through rate analysis but noisier for pricing.

  • US item view: https://www.ebay.com/itm/176543210987
  • UK item view: https://www.ebay.co.uk/itm/176543210987
  • DE item view: https://www.ebay.de/itm/176543210987
  • US sold comps search: https://www.ebay.com/sch/i.html?_nkw=iphone+13&LH_Sold=1&LH_Complete=1
  • US active search with category: https://www.ebay.com/sch/i.html?_nkw=vintage+camera&_sacat=625
  • Seller store front: https://www.ebay.com/str/sellerstorename
  • Product catalog page (catalog-backed): https://www.ebay.com/p/123456789
  • Paginated search: append &_pgn=2, &_pgn=3 — keep inter-page delay ≥ 3 s

3.eBay item page DOM structure and CSS selectors

eBay's item view page uses a component-based layout with predictable class names that have been stable across the Harmony design system. Price is rendered inside div.x-price-primary — the primary span.ux-textspans inside it holds the formatted amount including currency symbol. For auction listings, a secondary span.ux-textspans--BOLD near the bid section holds the bid count.

Item specifics live in div.ux-layout-section--item-specifics. Each row is a dl element; dt holds the attribute name, dd holds the value. Iterating dl elements gives you the full specifics map without relying on positional indexing.

The seller block is in div.ux-seller-section. The anchor tag inside span.ux-seller-section__item--seller holds the username as link text. Feedback score and positive percentage are in adjacent span elements within div.ux-seller-section__item--feedback. Shipping details — cost, carrier, and estimate — are in div.ux-labels-values--shipping, with individual span.ux-textspans elements for each piece of information.

Multi-variation listings (e.g., a shirt in multiple sizes and colors) render a variation selector above the price. The price shown before a variation is selected may be a range. Select a specific variation via URL parameter _var= if you need a single SKU price without JavaScript interaction.

Auction end time appears in span.ux-timer__text for active auctions with time remaining, and as a static timestamp in a nearby span with a data-end-date attribute on listings close to ending. Always prefer the data attribute over parsed text for machine-readable timestamps.

4.eBay bot detection: behavior and mitigation

eBay's bot management applies different pressure depending on the endpoint. Single item view pages (/itm/) at moderate request rates from residential IPs are the lowest-friction surface. Search endpoints (/sch/i.html) — especially sold listing search — are crawled heavily by many actors and receive stricter treatment: CAPTCHA challenges, IP blocks, and redirect loops are common from datacenter ranges.

Active auction pages present an additional challenge: bid count and time-remaining fields update via WebSocket or periodic XHR polling. A static HTML scrape captures the state at request time. If you need near-real-time bid tracking, use mode js_rendering with a js_wait_selector targeting the bid count element to ensure the initial JS render has completed before extraction.

Regional TLDs (ebay.de, ebay.fr, ebay.co.uk) share eBay's bot management infrastructure but maintain separate rate limit buckets. A burst against ebay.com does not consume your quota against ebay.co.uk, but the detection heuristics are identical.

The OmniScrape Web Unlocker handles CAPTCHA solving and challenge bypass automatically when enable_solver: true is set. For sold listing search — the highest-friction endpoint — combine residential proxy matching the TLD region with enable_solver: true and keep inter-request intervals above 3 seconds.

  • CAPTCHA and redirect challenges on /sch/i.html sold search at volume
  • IP-level blocks on datacenter ranges for search endpoints
  • Dynamic bid count and timer updates via JavaScript on active auctions
  • Geo-redirect responses when proxy region mismatches TLD
  • Layout variants: auction, fixed price, multi-variation, catalog-backed — each with slightly different DOM
  • Intermittent 429 responses on rapid sequential item view scrapes

5.Scrape an active eBay listing

Item view pages are the lowest-friction starting point. Use mode auto — OmniScrape will attempt a fast HTTP fetch first and escalate to browser rendering only if the response indicates a challenge or incomplete render. This keeps costs and latency low for the majority of item pages that serve complete HTML without JavaScript gating.

Match the proxy region to the eBay TLD. For ebay.com, use residential:us. The css_selectors map below covers the primary fields for both auction and fixed-price listings. Fields absent from the current listing type — such as bid_count on a fixed-price item — will return empty strings in body.data.css_extracted rather than errors.

The response HTML is in body.data.content. For css_extractor mode, extracted field values are in body.data.css_extracted as a key-value map matching your selector keys.

eBay item view — css_extractor request
json
1234567891011121314151617181920{
  "url": "https://www.ebay.com/itm/176543210987",
  "mode": "auto",
  "output_format": "css_extractor",
  "proxy": "residential:us",
  "enable_solver": true,
  "css_selectors": {
    "title": "h1.x-item-title__mainTitle span.ux-textspans",
    "price": "div.x-price-primary span.ux-textspans",
    "bid_count": "div.x-bid-count span.ux-textspans",
    "auction_end": "span.ux-timer__text",
    "bin_price": "div.x-bin-price span.ux-textspans",
    "shipping": "div.ux-labels-values--shipping span.ux-textspans",
    "condition": "div.x-item-condition-text span.ux-textspans",
    "seller": "div.ux-seller-section__item--seller a",
    "feedback_score": "div.ux-seller-section__item--feedback span.ux-textspans",
    "watchers": "div.ux-watchers span.ux-textspans",
    "quantity_available": "div.x-quantity__availability span.ux-textspans"
  }
}

6.Scrape sold listing search results

Sold comps data lives on eBay's search results pages filtered by LH_Sold=1&LH_Complete=1. Each result card is an li.s-item element inside ul.srp-results. The sold date appears in a span with class POSITIVE inside the tagblock — it renders as relative text ('Sold Jan 15, 2025') that you will need to parse into a structured date.

Sold search is the highest-friction endpoint. Use enable_solver: true and a residential proxy. Keep pagination slow — increment _pgn by one and wait at least 3–5 seconds between pages. Rapid sequential page fetches are the most common trigger for IP-level blocks on this endpoint.

Each result card link points to the completed listing's /itm/ URL. You can follow those links to extract full item specifics and seller details not available in the search card, but that doubles your request volume — only do it when the card data is insufficient.

eBay sold listings search — css_extractor request
json
123456789101112131415{
  "url": "https://www.ebay.com/sch/i.html?_nkw=vintage+camera&LH_Sold=1&LH_Complete=1&_pgn=1",
  "mode": "auto",
  "output_format": "css_extractor",
  "proxy": "residential:us",
  "enable_solver": true,
  "css_selectors": {
    "titles": "li.s-item h3.s-item__title",
    "sold_prices": "li.s-item span.s-item__price",
    "sold_dates": "li.s-item span.s-item__title--tagblock span.POSITIVE",
    "conditions": "li.s-item span.SECONDARY_INFO",
    "shipping": "li.s-item span.s-item__shipping",
    "links": "li.s-item a.s-item__link"
  }
}

7.Auction timing, bid tracking, and currency normalization

Auction end time is the most operationally sensitive field. Parse it from the data-end-date attribute on the timer element when available — it is an ISO 8601 string that does not require text parsing. The span.ux-timer__text display string ('2h 14m remaining') is for human display only; store the absolute UTC timestamp instead.

Active auctions update bid count and current price via JavaScript polling. A static HTML scrape captures the state at the moment of the request. For monitoring auctions in the final minutes — where sniping behavior drives rapid price changes — use mode js_rendering with js_wait_selector set to div.x-bid-count to ensure the JavaScript render has settled before extraction. Keep refresh intervals above 30 seconds to avoid rate limits.

Currency normalization is mandatory in multi-region pipelines. ebay.co.uk returns GBP, ebay.de returns EUR, ebay.com.au returns AUD. The currency symbol is embedded in the price text alongside the amount. Extract the ISO currency code from the regional TLD mapping rather than parsing the symbol — symbols are ambiguous ($, £, € can appear on multiple regional sites depending on proxy behavior). Store raw amount and currency code separately; apply FX conversion at query time, not at ingest time, so historical data remains accurate as rates change.

Best Offer listings do not expose the accepted offer price — only the asking price is public. If a listing ends without a visible sold price on the completed page, it likely sold via Best Offer. Flag these records separately rather than treating the asking price as the sale price.

8.Marketplace monitoring pipeline design

The natural primary key for eBay data is the numeric item ID from the /itm/ URL suffix. Item IDs are immutable — a seller cannot change the ID by editing the listing. Use item ID as the deduplication key across your scrape runs.

Listing lifecycle management is critical. Auctions end; fixed-price listings sell out or expire. A 404 response on an /itm/ URL means the listing is gone. A page that loads but shows an 'ended' banner — detectable via a CSS selector on div.vi-notify-msg or similar — means the listing completed. Mark records inactive on either signal; do not delete them, as historical price data retains value for comp analysis.

Separate your active-listing dataset from your sold-comps dataset at the schema level. Active listings change (price edits, relists, quantity updates). Sold comps are immutable once captured — a completed listing's final price does not change. Mixing them in the same table with the same update logic creates correctness problems.

For large item ID lists, async worker patterns distribute load and respect rate limits. See web scraping with Python for queue-based worker implementations. For the broader price monitoring use case — alert thresholds, time-series storage, competitor tracking — see price monitoring web scraping.

Deduplication on sold comps search requires care: the same completed listing can appear on multiple search result pages if your keyword matches multiple item specifics. Deduplicate on item ID after collection, not during.

9.eBay API, developer policies, and legal considerations

eBay provides official APIs through the eBay Developers Program — the Browse API, Buy API, and Finding API cover a significant portion of item search and detail retrieval use cases with structured responses and no scraping overhead. Evaluate whether the official API meets your data needs before building a scraping pipeline.

eBay's User Agreement restricts automated access and commercial redistribution of listing data. The practical and legal risk profile differs substantially between internal pricing research (using sold comps to value inventory) and building a product that republishes eBay listing data to third parties. Get legal review for any commercial application.

Robots.txt on ebay.com disallows crawling of search and sold listing pages for most user agents. This is a policy signal, not a technical block, but it is relevant to your legal and compliance assessment.

Rate limiting your scraper is both a technical necessity and a courtesy. eBay's infrastructure serves millions of real users; aggressive scraping degrades that experience and accelerates countermeasures that affect all automated access. Design for sustainable throughput — a pipeline that runs reliably at moderate speed is more valuable than one that saturates quickly and gets blocked.

Frequently asked questions

How do I get eBay sold prices for a product?

Use sold listing search URLs with LH_Sold=1&LH_Complete=1 appended to a standard eBay search URL. Results are HTML cards in ul.srp-results li.s-item. For valuation purposes, take the median sold price over 90 days rather than any single comp — outliers from damaged items or mislabeled listings skew averages significantly. If you need full item specifics for each sold listing, follow the /itm/ link from each card as a second request.

Why is bid count missing or zero on my scrape?

Fixed-price Buy It Now listings have no bids — bid_count will be empty for these. For active auction listings, bid count is rendered via JavaScript and may not appear in a static HTML fetch. Use mode js_rendering with js_wait_selector set to div.x-bid-count to wait for the bid section to render before extraction. If bid count is still missing, the auction may have zero bids, which eBay sometimes renders differently than a non-zero count.

Can I scrape eBay without residential proxies?

Single item view pages (/itm/) sometimes succeed from datacenter IPs at low volume and low frequency. Sold listing search (/sch/i.html with LH_Sold=1) fails much faster from datacenter ranges — it is a high-value endpoint that many actors target. For any production pipeline, residential proxies matched to the target TLD region (residential:us for ebay.com, residential:uk for ebay.co.uk) are the reliable baseline.

What is the difference between item ID (/itm/) and product page (/p/)?

Traditional eBay listings use /itm/NUMERIC — each listing is an independent item with its own seller, price, and condition. Catalog-backed product pages use /p/NUMERIC and aggregate multiple seller listings for the same product under a single canonical page. The /p/ page has a different DOM structure and requires different selectors. Store the URL type in your schema and handle them with separate extraction logic.

How do I handle multi-variation listings?

Multi-variation listings (e.g., a phone case in five colors and three sizes) show a price range before a variation is selected. To get a specific SKU price without JavaScript interaction, append the _var= parameter with the variation ID to the /itm/ URL — variation IDs are embedded in the page HTML as data attributes on the variation selector elements. Alternatively, use mode js_rendering and simulate a variation selection if you need all SKU prices in a single session.

How do I detect when a listing has ended?

A 404 response means the listing is fully removed. A 200 response with an ended banner — typically in div.vi-notify-msg or a similar alert element — means the listing completed but the page is still accessible for reference. Check for the ended state with a CSS selector on that element. For auctions, compare the scraped end time (UTC) against current time as a secondary signal — if end time is in the past and bid count is non-zero, the auction closed.

How should I normalize currency across regional eBay sites?

Map the eBay TLD to an ISO 4217 currency code at the pipeline level (ebay.com → USD, ebay.co.uk → GBP, ebay.de → EUR, ebay.com.au → AUD, etc.) rather than parsing currency symbols from price text — symbols are ambiguous and can vary based on proxy behavior. Store the raw numeric amount and the ISO currency code as separate fields. Apply FX conversion at query time using a rates table so historical records remain accurate as exchange rates change.

Related guides

  • E-commerce Web Scraping: Catalog Intelligence at Production Scale
  • Price Monitoring with Web Scraping: A Practical Developer Guide
  • Web Scraping with Python
  • Web Scraping Without Getting Blocked

Ready to scrape without blocks?

Get your API key in minutes. Test protected URLs from the dashboard — no credit card required to start.

Ready to get started?

Start scraping protected sites today — no credit card required.

OmniScrape

Web scraping infrastructure for developers. One API call to bypass any protection.

All systems operational

Product

  • Web Unlocker
  • Browser-as-a-Service
  • Residential Proxies
  • Pricing

Developers

  • API Reference ↗
  • Quickstart ↗
  • All Guides
  • Use Cases
  • Status

Company

  • About
  • Contact

Legal

  • Privacy Policy
  • Terms of Service
  • Refund Policy
  • Cookie Policy
  • Acceptable Use

Solutions

  • E-commerce Web Scraping: Catalog Intelligence at Production Scale
  • Real Estate Web Scraping: Listings, Comps, and Market Data
  • SERP Web Scraping: Agency Rank Tracking Workflow
  • Job Board Web Scraping: HR Tech Pipeline for Labor Market Intelligence
  • Price Monitoring with Web Scraping: A Practical Developer Guide
  • Lead Generation Web Scraping: Compliant Inbound Enrichment for Sales Teams
  • Market Research Web Scraping: Multi-Geo Data Collection for Research Firms
  • Sentiment Analysis Web Scraping: Build a Production Review Pipeline
  • Logistics Web Scraping: Carrier Rates, Port ETAs, and Sailing Schedules
  • Social Media Web Scraping: Brand Mention Monitoring from Public Pages
  • LLM Training Data Scraping: Building Clean Web Corpora
  • Travel Web Scraping: Hotel Rates, Flight Fares & Parity Monitoring

Web Scraping by Language

  • Web Scraping with Python
  • Web Scraping with Node.js: fetch, Cheerio, and the OmniScrape API
  • Web Scraping with Java: HttpClient, Jsoup, and OmniScrape API
  • Web Scraping with PHP
  • Web Scraping with Go (Golang)
  • Web Scraping with Ruby: Faraday, Nokogiri, Sidekiq & OmniScrape
  • Web Scraping with C#: HttpClient, AngleSharp, and OmniScrape API
  • Web Scraping with Rust
  • Web Scraping with R: httr2, rvest, and the OmniScrape API
  • Web Scraping with C++
  • Web Scraping with Elixir
  • Web Scraping with Perl: Mojo::UserAgent, Mojo::DOM, and OmniScrape

Anti-Bot Bypass

  • How to Bypass Cloudflare When Web Scraping
  • How to Bypass DataDome When Web Scraping
  • How to Bypass Akamai Bot Manager When Web Scraping
  • How to Bypass PerimeterX (HUMAN Security) When Web Scraping
  • Bypassing AWS WAF When Web Scraping: Rate Rules, Bot Control, and Residential Proxies
  • How to Bypass Imperva (Incapsula) When Web Scraping
  • How to Bypass Kasada Bot Protection When Web Scraping
  • How to Bypass F5 BIG-IP Bot Defense When Web Scraping
  • How to Bypass Distil Networks When Web Scraping
  • How to Bypass reCAPTCHA When Web Scraping

Scraping Tools

  • Playwright Web Scraping: Practical Patterns for Protected Sites
  • Puppeteer Web Scraping: Patterns, Anti-Bot Limits, and BaaS Integration
  • Selenium Web Scraping: Practical Patterns for Real-World Projects
  • Scrapy Web Scraping with OmniScrape: Download Middleware, Pipelines, and Scale
  • Beautiful Soup Web Scraping: A Practical Guide
  • cURL Web Scraping: Shell-Native Patterns with OmniScrape
  • HTTPX Web Scraping: Async Python with OmniScrape
  • Cheerio Web Scraping: A Practical Guide

Site-Specific Scrapers

  • Amazon Scraper: Product Data, Buy Box, Reviews, and Multi-Marketplace
  • Google Search Scraper: Extract SERP Rankings and Features
  • Google Maps Scraper: Extract Business Listings and Place Data
  • LinkedIn Scraper: Companies, Jobs, and Public Profiles
  • Walmart Scraper: Prices, Stock, Rollback Deals, and Fulfillment Data
  • eBay Scraper: Extract Listings, Auctions, and Sold Prices
  • Shopify Scraper: Products, Variants, and JSON Endpoints
  • Indeed Scraper: Extract Job Listings, Salaries, and Company Data
  • Zillow Scraper: Extract Listings, Zestimates, and Price History
  • Reddit Scraper: Posts, Comments, and Subreddit Data
  • X (Twitter) Scraper: Tweets, Profiles, and Hashtags
  • Instagram Scraper: Posts, Reels, and Profile Metrics
  • TikTok Scraper: Extract Videos, Hashtags, and Trend Data
  • YouTube Scraper: Extract Video Metadata, Comments, and Channel Stats
  • Booking.com Scraper: Hotel Rates, Room Types, and Availability
  • Airbnb Scraper: Listings, Calendars, and Nightly Rates
  • Crunchbase Scraper: Extract Funding Rounds, Companies, and Investors
  • Yelp Scraper: Extract Business Listings, Ratings, and Reviews
  • Glassdoor Scraper: Employer Ratings, Salaries, and Review Data
  • Trustpilot Scraper: TrustScore, Star Distribution, and Review Monitoring

How We Compare

  • OmniScrape vs ScrapingBee
  • OmniScrape vs ZenRows
  • OmniScrape vs ScraperAPI: A Practical Developer Comparison
  • OmniScrape vs Bright Data: Which Web Scraping Platform Fits Your Team?
  • OmniScrape vs Oxylabs
  • OmniScrape vs Smartproxy
  • OmniScrape vs Crawlbase: API Design, Observability, and Migration Guide
  • OmniScrape vs Apify

Web Scraping Guides

  • Web Scraping Without Getting Blocked
  • Web Scraping Proxy Guide: Types, Sessions, Geo, and OmniScrape Integration
  • Solve CAPTCHAs While Web Scraping
  • Web Scraping vs Web Crawling: Architecture, Patterns, and When to Use Each
  • Headless Browser Scraping: When to Use It and How to Do It Right
  • Web Scraping API: Endpoint, Modes, Output Formats & Integration Patterns
  • Rotating Proxies for Web Scraping: Policies, Session Binding, and Geo Pools
  • Scrape JavaScript-Rendered Pages: SPAs, Hydration, and Hidden APIs

© 2026 OmniScrape. All rights reserved.

PrivacyTermsRefundsAcceptable Use