Car & Classic [$1💰] | Full 46k catalogue | Beats 10k cap
Pricing
from $1.00 / 1,000 results
Car & Classic [$1💰] | Full 46k catalogue | Beats 10k cap
💰$1 per 1,000 listings. Scrape the FULL Car & Classic catalogue. The site's API serves only the first 10,000 results of any search, so rival scrapers stop there; this one slices automatically and gets all ~46,000 listings across Europe, with dealer phones and live auction bids.
Pricing
from $1.00 / 1,000 results
Rating
5.0
(2)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
0
Bookmarked
19
Total users
3
Monthly active users
4.9 hours
Issues response
7 days ago
Last modified
Categories
Share
Car & Classic Scraper
Turn Car & Classic into a structured classic-car dataset — the whole catalogue, not the first 10,000. Scrape listings from carandclassic.com with price, year, mileage, engine, gearbox, steering side, colour, location, seller details, photos, and live auction bids. Classic cars, motorcycles and commercial vehicles across the UK and Europe. JSON, CSV or Excel out, priced per result.
✨ Why use this scraper?
Car & Classic's own search API serves at most 10,000 results for any one search: 100 pages of 100, after which it refuses the next page. A scraper that pages until the API stops therefore ends with about a fifth of a 46,000-listing catalogue.
- 🔓 Gets past the 10,000 ceiling. When a search is bigger than the API will serve, the Actor automatically splits it into year slices, sweeps each, and de-duplicates. A full-catalogue run returns about 98% of the listings the site reports, instead of the first 10,000.
- 📣 Tells you when it falls short. Every run compares what it collected against the total Car & Classic itself reports, and says so in the log. No silent truncation.
- 🔗 Paste a search URL and it just works. Car & Classic's search URL uses the same parameters as its API, so a pasted URL reproduces the site's own result count exactly. Paste several to run several searches at once.
- 📞 Dealer contact details included. Dealer listings carry the trading name, phone number and website, alongside verification year — with no extra requests.
- 🔨 Live auctions with bids. Auction listings include the current bid, bid count, reserve status (set / met / lowered) and end time.
- 🌍 Pan-European, not just UK. GB ~20,700, France ~8,600, Italy ~7,100, plus the Netherlands, US, Belgium, Germany, Spain and more — filterable by country.
- 🔎 Full details on request. Turn on
includeDetailsand each listing gets one extra request for its creation date, vehicle group, the seller's full description, a body style read from it, every photo and, on dealer classifieds, the dealer's coordinates. - ⚡ 100 listings per request, no per-car fetches by default. Everything comes from the search API: the whole catalogue is about 470 requests and takes around 25 minutes.
🎯 Use cases
| Team | What they build |
|---|---|
| Classic dealers & traders | Pricing benchmarks by model, generation and condition across Europe |
| Collectors | Alerts on a specific generation or variant coming to market |
| Auction watchers | Live bid, reserve status and end-time tracking across every running auction |
| Market analysts | Classic-car value trends by make, era and country |
| Lead generation | Dealer directories from sellerName, sellerPhone, sellerWebsite and town |
| Restorers & parts traders | Finding project cars by mileage, year and price band |
| ML / data teams | Valuation training data with spec, location and listing history |
📥 Supported inputs
You don't need a URL. Set the filters and run. startUrls is optional:
| Input | Behaviour |
|---|---|
https://www.carandclassic.com/search?make=porsche&model=911 | Search — the query string maps 1:1 onto the API |
https://www.carandclassic.com/auctions | Auctions index: live auctions only. /make-an-offer works the same way for make-an-offer listings. Filters in the query string still apply. |
https://www.carandclassic.com/car/C2065581 | Single listing: that listing, as one row |
https://www.carandclassic.com/search | Everything: the search page with no filters is the whole catalogue, up to maxItems |
| Filters on the input | Same filters, set directly |
Each start URL can be a plain string or an object with a url key ({ "url": "https://www.carandclassic.com/car/C2065581" }), the shape many API clients send.
Pasted search URLs are the easiest route. Build the search on carandclassic.com, copy the URL, paste it in. Paste as many as you like — each is scraped as its own search and results are de-duplicated by listing ID across all of them, so overlapping searches never bill twice. maxItems is a total across every URL.
A start URL the Actor cannot read stops the run before anything is scraped. That covers a search URL whose parameters it does not recognise, and any other carandclassic.com page that is neither a search nor a single listing: a dealer page, an article, a listing URL with something added after the reference. The run stops even when the other URLs in the list are fine, and the error names the URL. That's deliberate: such a URL would otherwise fall through to scraping all ~46,000 listings instead of your selection.
The whole catalogue is only scraped when you ask for it: leave both startUrls and the filters empty, or paste the bare search page (https://www.carandclassic.com/search).
Single-listing URLs return exactly that listing. Paste a listing's own URL in any of the forms the site uses (/car/C2065581, /l/C2065581, /la/C2065581, /auctions/{slug} or /make-an-offer/{slug}) and you get one row for it. That row always carries the full details (the ones includeDetails adds to search results, description among them), whether or not includeDetails is on; its region is the broader one the listing's own record reports, and popularScore is empty. A run with only listing URLs returns those listings and nothing else. Mix them with search URLs or filters if you like: a listing that a search also finds is returned once, and listing URLs count towards maxItems. A listing that is no longer on the site is named in the log and skipped.
Not supported: hosts outside carandclassic.com, and anything in startUrls that is not a URL. Those entries are skipped with a warning in the log while the run has something else to do (another start URL, or filters on the input). If they are all the run was given, it stops with an error and returns nothing.
🔄 How it works
- Translate your filters, or the query string of any pasted search URL, into API parameters.
- Ask the API how many listings match — the same number the website prints.
- Slice if needed. Above ~10,000 the year range is bisected recursively until every slice fits under the ceiling.
- Sweep each slice at 100 listings per request, de-duplicating by listing ID.
- Fetch details, if asked. With
includeDetailson, each listing's own record is read for the fields search leaves out. - Report coverage — collected versus reported, with any shortfall stated explicitly.
Single-listing URLs skip all of that: each one is a single request for that listing, made before any search starts.
⚙️ Input parameters
| Field | Type | Description |
|---|---|---|
startUrls | array | Car & Classic search URLs, single-listing URLs, or both, as strings or { "url": … } objects. Optional. |
maxItems | integer | Maximum listings. Default 1000. |
includeDetails | boolean | One extra request per listing to fill createdAt, modifiedAt, vehicleGroup, description, bodyTypeFromText, every photo URL and dealer coordinates. Default false. |
makes | array | Make slugs as they appear in a URL, e.g. ["porsche","alfa-romeo"]. Each runs as its own search. |
model / variant / generation | string | Slugs, e.g. 911, gt3, 991-2. |
keywords | string | Free-text search. |
vehicleType | string | Cars, motorcycles or commercial vehicles. |
listingType | string | Auctions only, classifieds only, or both. |
priceMin / priceMax | integer | Price range in whole currency units. |
yearMin / yearMax | integer | Year range. |
mileageMin / mileageMax | integer | Mileage range. |
engineSizeMinCc / engineSizeMaxCc | integer | Engine capacity in cc. |
colours | array | Exterior colour. |
transmission | string | Manual or automatic. |
steeringPosition | string | LHD or RHD. |
sellerType | string | Dealer or private. |
country | string | ISO country code, e.g. GB, FR, IT. |
maxConcurrency | integer | Parallel dataset writes, and parallel detail requests with includeDetails. Default 10. |
Example input
{"startUrls": ["https://www.carandclassic.com/search?make=porsche&model=911"],"maxItems": 500}
Two listings by URL, and only those:
{"startUrls": ["https://www.carandclassic.com/car/C2065581","https://www.carandclassic.com/l/C2208400"]}
Every live auction, with bids:
{"listingType": "auctions","maxItems": 500}
📊 Output overview
One row per listing. Classifieds and auctions share a single shape — auction-only fields come back null on classifieds, and dealer-only fields come back null on private sales, so the column set never changes between rows.
📦 Output sample
{"listingId": "2241780","listingUrl": "https://www.carandclassic.com/la/C2131760","listingType": "basic","title": "2018 Porsche 911 GT3","make": "Porsche","model": "911","variant": "GT3","generation": "991.2","year": 2018,"price": 149900,"currency": "EUR","mileage": 43500,"mileageUnit": "km","engineSizeCc": 4000,"fuelType": "petrol","transmission": "automatic","gears": "7+","steeringPosition": "lhd","colour": "Red","vehicleGroup": "car","country": "France","countryCode": "FR","town": "Paris","latitude": 48.8247842,"longitude": 2.3678611,"sellerType": "dealer","sellerName": "Sportwagen Paris","sellerPhone": "+33187227763","sellerWebsite": "http://sportwagenparis.com","isAuction": false,"currentBid": null,"bidCount": null,"imageCount": 11,"createdAt": "2026-08-13T09:26:53+00:00","scrapedAt": "2026-08-18T15:17:25.862Z"}
vehicleGroup, latitude, longitude, description, bodyTypeFromText, createdAt and modifiedAt are filled when includeDetails is on, and always for a listing given by its own URL. Otherwise they are null, and images holds the first five photos.
🗂 Key output fields
| Field | Notes |
|---|---|
listingId | Stable ID. Use it to de-duplicate across scheduled runs. |
price | Asking price, or the current bid on a live auction. |
currency | Check this. The site is pan-European, so GBP and EUR both appear. |
mileage / mileageUnit | Check the unit — European listings are in km, UK ones in miles. |
sellerPhone / sellerWebsite | Dealer listings only; null for private sellers. |
isAuction | True for live auctions. Auction fields are null on classifieds. |
currentBid / bidCount / reserveMet | Live auction state at the moment of scraping. |
latitude / longitude | The dealer's premises, on dealer classifieds. Needs includeDetails or a listing URL. |
images / imageCount | images holds the first five photos, or all of them with includeDetails or a listing URL. imageCount is always the full number. |
description | The seller's full write-up as plain text, line breaks kept. Needs includeDetails or a listing URL. |
bodyTypeFromText | convertible, targa, coupe, saloon, estate or hatchback, read from the seller's wording in the title and description. A reading, so it can be wrong, and null when the wording does not settle it. Cars only. Needs includeDetails or a listing URL. |
createdAt / modifiedAt | Need includeDetails or a listing URL. modifiedAt is set on auctions and make-an-offer listings only. |
generation | e.g. 991.2 — Car & Classic is unusually good at generation data, which matters for valuation. |
❓ FAQ
Why do other Car & Classic scrapers stop at around 10,000? Because the API serves only the first 100 pages of 100 results for any one search and refuses the page after that. This Actor splits a larger search into year slices that each fit under the limit.
Can I get all ~46,000 listings? Close to it. A full sweep returns about 98% of what the site reports: 46,637 of 47,375 in a run on 11 October 2026. The gap is listings with no year (which fall outside every year slice) plus normal churn during a multi-minute run. The Actor reports the exact shortfall in the log rather than hiding it.
Can I get sold or completed auction results?
No. Car & Classic's API only exposes currently-live auctions, so hasSold and soldAt stay empty. Only live bidding state is available.
Do I need a proxy? No. Car & Classic sits behind Cloudflare, but the Actor's HTTP stack handles it without one, and direct connections are both faster and free.
Why are createdAt, latitude or vehicleGroup empty?
Car & Classic's search results stopped carrying them in October 2026. Turn on includeDetails and the Actor reads each listing's own record to fill them, at the cost of one extra request per listing. bodyType, doors, category, province, collections, tags, hasInspection and hasVrn are no longer published at all, so those columns stay empty. For the body style, bodyTypeFromText gives a reading from the seller's own wording.
How reliable is bodyTypeFromText?
It reads the body style from the seller's title and description, because Car & Classic no longer publishes one. A body word in the title is taken as it stands. The description counts only when the title says nothing, and only when it names a single body style. In a check of 610 Porsche 911 listings it labelled 283 and left 327 empty, where the seller never named the body. It can be wrong when a description mentions one body style in passing, so treat it as a strong hint and read the title or description where it matters.
Why is mileageUnit sometimes km?
Because the listing is in mainland Europe. Always read mileage together with mileageUnit.
💬 Support
- Issues tab on the Actor page
- Email: muhamed.didovic@gmail.com
🛠 Additional services
- Custom output shape, additional fields, or one-off datasets: muhamed.didovic@gmail.com
- Need a similar scraper for another classic-car marketplace (Bring a Trailer, Classic Trader, Catawiki)? Drop an email.
- For API access (no Apify fee, just a usage fee for the API): muhamed.didovic@gmail.com
🔎 Explore more scrapers
For auction results, see the Collecting Cars scraper: live auctions plus ~33,000 sold results with their sale prices. Other scrapers at memo23's Apify profile include the PistonHeads and AutoTrader UK scrapers, plus job boards, real estate and more.
🤖 For AI Agents & LLM Apps
- Deterministic input. All filters are plain JSON; make and model take the same slugs as the website URL.
- Stable schema. Every field is present on every row (
nullwhen absent), so downstream parsing needs no defensive key checks. - Bounded cost.
maxItemscaps the result count exactly. - Honest coverage. The run states collected-versus-reported totals, so an agent can tell whether it has a complete set.
- Grounding-friendly.
listingUrlgives every row a citable public source;scrapedAtsupports freshness reasoning, as doescreatedAtwhenincludeDetailsis on.
⚠️ Disclaimer
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Car & Classic Ltd or any of its subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.
The scraper accesses only publicly available listing pages and the public search endpoint on carandclassic.com — no authenticated endpoints, dealer-only features, or content behind a login. Users are responsible for ensuring their use complies with Car & Classic's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.
SEO Keywords
car and classic scraper, carandclassic scraper, classic car scraper, classic car listings api, classic car data, scrape carandclassic.com, Apify car and classic, classic car marketplace scraper, classic car auction scraper, classic car prices uk, european classic car listings, vintage car scraper, collector car data, classic car dealer leads, porsche 911 listings scraper, classic car valuation data, car auction bids scraper, classic motorcycle listings scraper, bring a trailer alternative, collecting cars alternative, classic trader alternative, uk classic car market data