npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

autotrader-scraper

v1.0.0

Published

Scraper for the vehicle marketplace, AutoTrader (UK)

Downloads

12

Readme

AutoTrader Scraper

Scraper for the online vehicle marketplace, AutoTrader (UK). Built with Node and makes heavy use of Nightmare.js for browser automation.

⚠️ While run headlessly, Nightmare.js uses Electron to automate a browser window. This requires all of Electron's dependencies to be met which includes various UI focused packages. This may be an issue on various server distros.

Features

  • Perform flexible searches using all site-available criteria
  • Retrieve all significant data from adverts
  • ~~Login to an AutoTrader UK account to access saved adverts~~
  • Retrieve Dealer data and their stock
  • Supports cars, vans and bikes

❌ Due to recent and ongoing AutoTrader.co.uk changes, account features are currently disabled as of the 3rd of March 2019. These features will be reimplemented when new changes stop being made to the site's account system.

Installation

Install AutoTrader Scraper via npm by doing the following:

npm i autotrader-scraper --save
// yourscript.js
const AutoTraderScraper = require('autotrader-scraper')

Don't have node/npm installed? Get it here

Tests

Perform core functionality tests via the following:

npm test

Usage & Examples

Create an AutoTraderScraper object to begin:

const autotrader = new AutoTraderScraper()

Searching

Perform a search and retrieve the results via the following:

const criteria = {
    // required
    location: {
      radius: 1500,
      postcode: "BH317LE"
    },
    // optional
    make: 'ford',
    condition: ['New', 'Nearly New', 'Used']
}
const results = await autotrader.search('cars').for({ criteria })
    .then(listings => listings.literals)
    // or use .json to return as a JSON string

NOTE: A large amount of other criteria are supported and will be detailed at the end.

Retrieve a number of results

You can specify an amount of results to get by either specifying the number of pages or number of results you wish to retrieve:

const criteria = { /* define criteria */ }
const results = await autotrader.search('cars').for({ criteria, pages: 2 })
    .then(listings => listings.literals)
    // or use .json to return as a JSON string

or

const criteria = { /* define criteria */ }
const results = await autotrader.search('cars').for({ criteria, results: 50 })
    .then(listings => listings.literals)
    // or use .json to return as a JSON string

When giving a number of results, they will be converted to pages when parsed by the search object. Each page contains 13 results so the number of results will not be true to the input but rather rounded up to a number divisible by 13. This means, specifying results: 50 will be converted to pages: 4.

Metadata

You can retrieve data about the search via the returned SearchResult object.

const criteria = { /* define criteria */ }
const results = await autotrader.search('cars').for({ criteria, results: 50 })
const searchURL = results.url // the url used to perform the search
const averagePrice = results.average.price // average price of retrieved results
const averageMileage = results.average.mileage // average mileage of retrieved results
const dateOfSearch = results.date.string // or as an int
const possibleResults = results.searchResultCount // number of results on AutoTrader.co.uk
const retrievedResults = results.retrievedResultCount // number of results retrieved by the scrape
// the above is an alias for .listings.length and can also be retrieved via .count or .length

Retrieving Adverts

Retrieve data from an advert URL. These URLs can be retrieved from search result objects via the url property or provided by yourself.

const advertURL = 'https://autotrader.co.uk/classified/advert/201810101381913'
const result = await autotrader.get.advert.from(advertURL)
    .then(advert => advert.literal)
    // or use .json to return as a JSON string
/* as this method requires the use of Nightmare to execute on-site Javascript,
 * we must close the Nightmare instance once we're done with it */
await autotrader.exit()

To be efficient, you should retrieve all desired adverts before closing the Nightmare instance to avoid having to initialise a new instance every time.

Retrieving Dealers

Retrieve data from a dealer URL.

const dealerURL = 'https://www.autotrader.co.uk/dealers/hampshire/southampton/southampton-van-centre-10009006'
await autotrader.get.dealer.from(dealerURL)
    .then(dealer => dealer.literals)
    // or use .json to return as a JSON string
/* as this method requires the use of Nightmare to execute on-site Javascript,
 * we must close the Nightmare instance once we're done with it */
await autotrader.exit()

To be efficient, you should retrieve all desired adverts before closing the Nightmare instance to avoid having to initialise a new instance every time.

Account Access

❌ Due to recent and ongoing AutoTrader.co.uk changes, account features are currently disabled as of the 3rd of March 2019. These features will be reimplemented when new changes stop being made to the site's account system.

Login to an AutoTrader UK account to use account related features. Currently, this is just the saving and retrieval of saved adverts.

These methods require a Nightmare instance. Remember to exit this instance when you're done with it via the exit method. Once the instance has been exited, you must login again to use any account related features.

const credentials = {
    email: '[email protected]',
    password: 'hunter2'
}
await autotrader.login(credentials)

You can easily log back out of this account via the following:

await autotrader.logout()
// then close the Nightmare instance if we're done with it
await autotrader.exit()

Saved Adverts

When logged in to an AutoTrader UK account, you can save adverts to add them to your account's 'Saved Adverts' list.

const advertURL = 'https://autotrader.co.uk/classified/advert/201810101381913'
await autotrader.save(advertURL)

You can also remove (unsave) an advert from your account's 'Saved Adverts' list.

const advertURL = 'https://autotrader.co.uk/classified/advert/201810101381913'
await autotrader.unsave(advertURL)

Retrieve your account's saved adverts via the following:

 // get all saved adverts
 const savedAdverts = await autotrader.get.all.saved.adverts()
  .then(results => results.literals)
 // get specific page of saved adverts (e.g. page 1 for most recent)
 const newestSavedAdverts = await autotrader.get.saved.adverts({ page: 1 })
 .then(results => results.literals)

⚠️ Remember to exit the Nightmare instance once we're done with it to avoid memory leaks.

Criteria

| Key | Definition | Validation | |:---:|---|---| |location.radius|The maximum distance from the given postcode (in miles)|Integers| |location.postcode|The postcode in which to centre the search from|String| |condition|The vehicle's condition|New, Nearly New, Used| |price.min|The minimum price|Integers| |price.max|The maximum price|Integers| |make|The vehicle's make (e.g. Ford, Nissan)|Validated against a list of car makes| |model|The vehicle's model (e.g. Focus, c4)|String| |variant|The vehicle's variant (e.g. ST, EcoBoost)|String| |year.min|The minimum year of manufacture|Integers| |year.max|The maximum year of manufacture|Integers| |mileage.min| The minimum mileage |Integers| |mileage.max| The maximum mileage |Integers| |wheelbase| The vehicle's wheelbase. Vans only|L, M, S, LWB, SWB, MWB, {Wheel base unlisted}| |cab|The vehicle's cab type. Vans only|Crew cab, Double cab, Day cab, High sleeper cab, Low access cab, N, Short cab, Standard cab, Transported cab, Y, {Cab type unlisted}| |cc.min|The minimum CC. Bikes only.|0, 50, 125, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1600, 1800, 2000| |cc.max|The maximum CC. Bikes only.|0, 50, 125, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1600, 1800, 2000| |body|The vehicle's body type|Convertible, Coupe, Estate, Hatchback, MPV, Other, Pickup, SUV, Box Van, Camper, Car Derived Van, Chassis Cab, Combi Van, Combi +, Crew Cab, Curtain Side, Dropside, Glass Van, High Roof Van, King Cab, Low Loader, Luton, MPV, Medium, Minibus, Panel Van, Platform Cab, Specialist Vehicle, Temperature Controlled, Tipper, Vehicle Transporter, Window Van, Adventure, Classic, Commuter, Custom Cruiser, Enduro, Minibike, Moped, Motocrosser, Naked, Quad/ATV, Roadster/Retro, Scooter, Special, Sports Tourer, Super Moto, Super Sports, Supermoto-Road, Three Wheeler, Tourer, Trail (Enduro), Trail Bike, Trial Bike, Unlisted| |fuel.type|The vehicle's fuel type|Bi Fuel, Diesel, Electric, Hybrid - Diesel/Electric, Hybrid - Diesel/Electric Plug-in, Hybrid - Petrol/Electric, Hybrid - Petrol/Electric Plug-in, Petrol, Petrol Ethanol, Unlisted| |fuel.consumption|The vehicle's average fuel consumption|OVER_30, OVER_40, OVER_50, OVER_60| |engine.min|The minimum size of the engine|0, 1.0, 1.2, 1.4, 1.6, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0| |engine.max|The maximum size of the engine|0, 1.0, 1.2, 1.4, 1.6, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0| |acceleration|The seconds taken for the vehicle to go from 0 to 60|TO_5, TO_8, 8_TO_12, OVER_12| |gearbox|The type of vehicle's gearbox |Automatic, Manual| |drivetrain|The type of the vehicle's drivetrain |All Wheel Drive, Four Wheel Drive, Front Wheel Drive, Rear Wheel Drive| |emissions|The vehicle's average co2 emissions|TO_75, TO_100, TO_110, TO_120, TO_130, TO_140, TO_150, TO_165, TO_175, TO_185, TO_200, TO_225, TO_255, OVER_255| |doors|The vehicle's number of doors|0, 2, 3, 4, 5, 6| |seats.min|The minimum number of seats that the vehicle has|1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12| |seats.max|The maximum number of seats that the vehicle has|1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12| |insurance|The vehicle's insurance group|10U, 20U, 30U, 40U| |tax|The annual price of the vehicle's tax|EQ_0, TO_20, TO_30, TO_110, TO_130, TO_145, TO_185, TO_210, TO_230, TO_270, TO_295, TO_500, OVER_500| |colour|The vehicle's colour|Beige, Black, Blue, Bronze, Brown, Burgundy, Gold, Green, Grey, Indigo, Magenta, Maroon, Multicolour, Navy, Orange, Pink, Purple, Red, Silver, Turquoise, Unlisted, White, Yellow| |excludeWriteOffs|Boolean to exclude written off vehicles from the results|true, false| |onlyWriteOffs|Boolean to only include written off vehicles in the results|true, false| |customKeywords|Keywords that should be used to narrow down the search. Is unpredictable but may be useful if the above criteria do not meet your needs.|String or Array|

Things To Note

Condition

When defining the condition criteria, you can use either a string or array. An array value allows you to search multiple types of conditions in a single search. For example, the following snippet will retrieve cars in new or nearly new condition.

const criteria = {
    location: {
      radius: 1500,
      postcode: "BH317LE"
    },
    condition: ['New', 'Nearly New']
}
const results = await autotrader.search('cars').for({ criteria })
    .then(listings => listings.literals)
Custom Keywords

The custom keywords parameter must be sent in a single string but for improved readability, you can define the customKeywords criteria as a string or an array.

const criteria = {
    location: {
      radius: 1500,
      postcode: "BH317LE"
    },
    condition: ['New', 'Nearly New', 'Used'],
    customKeywords: ['leather seats', 'air conditioning'] // and
    customKeywords: 'leather seats air conditioning'      // are both functionally the same
}
const results = await autotrader.search('cars').for({ criteria })
    .then(listings => listings.literals)