PistonHeads.com [$1💰] | Full 208k catalogue | Real pagination
Pricing
from $1.00 / 1,000 results
PistonHeads.com [$1💰] | Full 208k catalogue | Real pagination
💰$1 per 1,000 cars. Scrape the FULL PistonHeads catalogue — rival scrapers loop on page one because the site ignores its own page parameter. Get price, mileage, spec, seller and photos per car. Filter by make, model, price, year, mileage or postcode radius. Optional descriptions + galleries.
Pricing
from $1.00 / 1,000 results
Rating
5.0
(1)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
PistonHeads Car Scraper
Turn PistonHeads into a structured UK used-car dataset — the whole catalogue, not just page one. Scrape car adverts from PistonHeads with price, year, mileage, fuel, gearbox, body style, colour, engine size and power, seller name, type, location and phone, listing date, and photos. Filter by make, model, price, year, mileage, postcode radius and more — or pull every car listed in the last 24 hours. JSON, CSV or Excel out, priced per result.
How it works

✨ Why use this scraper?
Most PistonHeads scrapers quietly return the same first page over and over. That isn't their bug — it's the site's. PistonHeads ignores ?page= on its search URL entirely and renders no pagination links at all, because filtering and paging happen client-side after the page loads. Scrape that HTML and you loop on the first ~16 cars forever, however many pages you ask for.
- 🔁 Pagination that actually reaches the end. This Actor drives the site's own JSON API and walks
offsetin steps of 100 — verified working past offset 200,000 on a catalogue of roughly 208,000 cars. - ⚡ 100 complete cars per request, zero per-car fetches. Price, full specification, seller and images all arrive in the search response, so a 250-car pull takes about 9 seconds. Most scrapers make one request per car.
- 🔤 Makes and models by name, not internal IDs. Ask for
Porsche+911and the Actor resolves it against PistonHeads' own lists — including all 19 generation variants (911 Carrera [991],911 GT3 [992],911 [964], …) that you'd otherwise have to enumerate by hand. - 🕒 Daily new-listings monitoring.
listedWithinHours: 24returns only cars listed today, so a scheduled run costs a few hundred rows instead of re-scraping the catalogue. - 🎛 Filters that match the site's own refine panel. Price, year, mileage, engine size, power, previous owners, fuel, gearbox, body, colour, drivetrain, doors, seats, trade vs private, postcode + radius, and free-text keywords.
- 📝 Optional advert copy and full photo gallery. Turn on one flag to add the seller's written description, the features list, the full trim string, and every photo instead of the four the search API returns.
- 🔓 No login, no captcha, no browser. The data source is a public endpoint, so runs are fast and cheap.
🎯 Use cases
| Team | What they build |
|---|---|
| Dealers & traders | Live pricing benchmarks for stock they hold or want to buy |
| Car buyers & flippers | Daily alerts on new listings matching a tight spec, before they're gone |
| Market analysts | Depreciation and price-trend datasets by make, model, generation and mileage band |
| Classic & specialist brokers | Watch a specific generation (e.g. 911 [993]) across the whole market |
| Lead generation | Dealer directories built from sellerName, sellerType, sellerLocation and sellerPhone |
| Price-comparison sites | Structured inventory feeds refreshed on a schedule |
| ML / data teams | Training data for valuation models — spec, mileage, price and listing date per car |
📥 Supported inputs
You don't need a URL at all. Set the filters and run — that's the primary path. startUrls is optional:
| URL pattern | Behaviour |
|---|---|
https://www.pistonheads.com/buy/listing/{id} | Single advert — scraped directly, with the same fields as a search result |
https://www.pistonheads.com/buy/search?... | Search — recognised query parameters are translated into API filters |
About pasted search URLs. This is the easiest workflow: build your search on pistonheads.com, copy the URL out of the address bar, paste it into startUrls. The Actor reads the whole query string — makes, models, price, year, mileage, engine size and power, fuel, gearbox, body, colour, drivetrain, doors, seats, seller type, postcode and radius, keywords, and sort order — and applies the identical filters. Because PistonHeads puts the make and model IDs straight into the URL, a pasted search reproduces the site's own result count exactly.
Paste as many search URLs as you like. Each one is scraped as its own search, and results are de-duplicated by advert ID across all of them, so overlapping searches never bill you twice for the same car. Note that maxItems is a total across every URL, so set it high enough to cover the lot.
Anything you set on the input overrides what's read from a URL, so you can paste a search and then, say, tighten the price range on the input.
If the Actor cannot read any filters from a URL you paste, it stops with an error instead of running. That's deliberate: an unreadable URL would otherwise fall through to scraping the entire 208,000-car catalogue rather than your selection.
Not supported: seller/dealer profile pages as a starting point, forum threads, and hosts outside pistonheads.com.
🔄 How it works
- Resolve make and model names into PistonHeads' internal IDs using the site's own refine-panel facets. An unmatched make stops the run rather than silently widening the search to all 208,000 cars.
- Scrape any direct advert URLs supplied in
startUrls. - Page the catalogue via
searchPage(offset: N, limit: 100), walking offset untilmaxItemsor the end of the result set. Adverts are de-duplicated by ID, because a live catalogue shifts under you as new cars are listed mid-run. - Optionally fetch each advert's own page for the seller's description, features, trim string and full photo gallery.
- Push one row per car to the dataset.
⚙️ Input parameters
| Field | Type | Description |
|---|---|---|
startUrls | array | Optional advert or search URLs. Leave empty to search by filters alone. |
maxItems | integer | Maximum cars to return. Default 1000. |
makes / models | array | Names, e.g. ["Porsche"] / ["911"]. Models require a make. |
keywords | string | Free text across advert headlines. |
priceMin / priceMax | integer | Asking price range in GBP. |
yearMin / yearMax | integer | Registration year range. |
mileageMin / mileageMax | integer | Recorded mileage range. |
engineSizeMinCc / engineSizeMaxCc | integer | Engine capacity in cc (2000 = 2.0 litres). |
enginePowerMinBhp / enginePowerMaxBhp | integer | Engine power in bhp. |
maxPreviousOwners | integer | Maximum previous keepers. |
fuelTypes | array | Petrol, Diesel, Electric, Hybrid, LPG, Other. |
transmissions | array | Automatic, Manual, Other. |
bodyTypes | array | Convertible, Coupe, Estate, SUV, Hatchback, Saloon, MPV, Pick Up, Other. |
colours | array | 19 colours, from Black to Turquoise. |
driveTrains | array | Front-wheel drive, Rear-wheel drive, 4-wheel drive, Other. |
doors / seats | array | Door and seat counts. |
sellerType | string | Trade, Private, or empty for both. |
postcode + distanceMiles | string + integer | Search around a UK postcode. Adds distanceFromPostcodeMiles to each row. |
listedWithinHours | integer | Only adverts listed in the last N hours. 24 = today. |
includeSoldCars | boolean | Include adverts marked sold. Default false. |
sortOption | string | PistonHeads sort option, passed through. |
includeDescription | boolean | Add the advert's own write-up: description, features, trim and full gallery. Seller name/type/location/phone come free without it. One extra request per car. Default false. |
maxConcurrency | integer | Parallel description fetches. Default 10. |
Example input
{"makes": ["Porsche"],"models": ["911"],"priceMin": 40000,"priceMax": 90000,"transmissions": ["Manual"],"maxItems": 500}
Daily new-listings monitor:
{"listedWithinHours": 24,"maxItems": 2000}
📊 Output overview
One row per car advert. Every field is always present — missing source data comes back as null (or []), so your columns never disappear between rows.
📦 Output sample
{"listingId": "19910033","listingUrl": "https://www.pistonheads.com/buy/listing/19910033","title": "PORSCHE 911 TURBO CABRIOLET MANUAL 996","make": "Porsche","model": "911 Turbo [996]","year": 2004,"listedAt": "2026-02-18T08:00:00Z","price": 40990,"currency": "GBP","priceOnApplication": false,"priceOnAuction": false,"vatOmitted": false,"pricingModel": "Visible","mileage": 65000,"fuelType": "Petrol","transmission": "Manual","bodyType": "Convertible","colour": "Black","engineSizeCc": 3600,"enginePowerBhp": 420,"sellerId": "617798","sellerName": "Dorset Sports Cars","sellerType": "Trade","sellerLocation": "Wimborne, United Kingdom","sellerIsOnlineRetailer": false,"distanceFromPostcodeMiles": null,"sellerPhone": "01483967169","mainImage": "https://img.pistonheads.com/Fullsize/porsche/911-turbo-996/...","images": ["https://img.pistonheads.com/Fullsize/..."],"imageCount": 4,"isFeatured": false,"brandType": "Core","badges": [],"description": null,"features": null,"variant": null,"galleryImages": [],"galleryImageCount": 0,"scrapedAt": "2026-08-17T15:40:40.033Z"}
🗂 Key output fields
| Field | Notes |
|---|---|
listingId / listingUrl | Stable advert ID and its public URL. Use the ID to de-duplicate across scheduled runs. |
make / model | model carries the generation, e.g. 911 Turbo [996] — useful for valuation work. |
variant | Full trim string, e.g. 4.2 FSI V8 Estate 5dr S Tronic quattro (450 ps). Requires includeDescription. |
listedAt | When the advert went live. Pairs with listedWithinHours for monitoring. |
price | Integer GBP. Check priceOnApplication / priceOnAuction before treating it as an asking price. |
engineSizeCc / enginePowerBhp | Present on roughly 8 in 10 cars — older classics often have neither on PistonHeads. |
sellerType | Trade or Private. The catalogue skews heavily to trade. |
sellerPhone | Seller's phone number. Dealers publish a full number; PistonHeads masks private-seller numbers (e.g. 07984XXXXXX), so treat those as partial. |
distanceFromPostcodeMiles | Only populated when you set a postcode. |
images / imageCount | Capped at 4 by the search API. For the full set use galleryImages. |
galleryImages | Every photo (commonly 25–45). Requires includeDescription. |
features | Structured features list, typically 100+ entries on dealer adverts. Often null on private-seller adverts, which usually don't include one — that's the source data, not a parse failure. |
❓ FAQ
Why do other PistonHeads scrapers stop after one page?
Because they scrape the search HTML and loop ?page=2, ?page=3. PistonHeads ignores that parameter — pages 2, 50 and 500 all return the same first adverts. This Actor uses the site's JSON API with real offset pagination instead.
Can I get all 208,000 cars?
Yes. Set maxItems accordingly and leave the filters empty. Be deliberate about it — you're charged per result.
Does models need the exact PistonHeads name?
No. 911 matches all 19 generation variants. An exact name matches just that one. The run log always lists what your input resolved to.
Why is features empty on some cars?
Private-seller adverts usually don't include a features list. Dealer adverts almost always do.
Do I need a proxy? No. The default residential proxy is used and works, but PistonHeads isn't aggressive about blocking.
How do I run this daily for new listings only?
Set listedWithinHours: 24 and schedule the Actor once a day. De-duplicate on listingId if you're appending to your own store.
Are sold cars included?
Not by default. Set includeSoldCars: true if you want them.
💬 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 other car marketplaces (AutoTrader UK, AutoScout24, Motors, CarGurus, etc.)? Drop an email.
- For API access (no Apify fee, just a usage fee for the API): muhamed.didovic@gmail.com
🔎 Explore more scrapers
If this PistonHeads Scraper was useful, see other scrapers and actors at memo23's Apify profile — covering car marketplaces, job boards, real estate, social media, and more.
🤖 For AI Agents & LLM Apps
This Actor is a clean data source for agent pipelines and RAG over the UK used-car market.
- Deterministic input. All filters are plain JSON — no URL construction needed. Make and model take human names, so an LLM can pass
"Porsche"/"911"straight through from a user's question. - Stable schema. Every field is present on every row (
nullwhen absent), so downstream parsing never needs defensive key checks. - Bounded cost.
maxItemscaps the result count exactly;listedWithinHourskeeps incremental runs small. - Grounding-friendly.
listingUrlgives every row a citable public source, andlistedAt+scrapedAtlet an agent reason about freshness.
Typical agent tasks: "find manual 911s under £90k within 50 miles of Bristol", "track this week's new EV listings under £25k", "build a price-vs-mileage curve for the 997 generation".
⚠️ Disclaimer
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by PistonHeads, CarGurus, or any of their subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.
The scraper accesses only publicly available car adverts and the public search endpoint on pistonheads.com — no authenticated endpoints, dealer-only features, or content behind a PistonHeads login. Users are responsible for ensuring their use complies with PistonHeads' Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.
SEO Keywords
pistonheads scraper, scrape pistonheads, pistonheads api, pistonheads.com scraper, Apify pistonheads, uk car listings scraper, used car scraper uk, car classifieds scraper, uk car marketplace data, car price data uk, used car price api, car dealer scraper uk, vehicle listings scraper, car market analysis uk, porsche listings scraper, classic car scraper uk, autotrader alternative scraper, motors.co.uk alternative scraper, cargurus alternative scraper, car depreciation data, uk vehicle pricing dataset, car inventory feed uk, second hand car data uk