Blocket.se Car Scraper: All Swedish listings avatar

Blocket.se Car Scraper: All Swedish listings

Pricing

from $0.80 / 1,000 results

Go to Apify Store
Blocket.se Car Scraper: All Swedish listings

Blocket.se Car Scraper: All Swedish listings

Scrape every car on Blocket.se — price with and without VAT, mileage in km, VIN, registration plate, battery kWh, equipment, all photos, plus seller phone, email, website and address. Splits past Blocket's 2,450-per-search limit to reach all ~144,000 listings. JSON or CSV.

Pricing

from $0.80 / 1,000 results

Rating

0.0

(0)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

22

Total users

6

Monthly active users

17 hours ago

Last modified

Share

Blocket.se Scraper

Blocket.se Scraper

Every car on Blocket.se — not the first 2,450. Paste any Blocket search URL and get one clean row per car: price with and without VAT, mileage in kilometres, VIN, registration plate, battery capacity, full equipment list, every photo at full resolution, and the seller's phone, email, website and postal address. Roughly 144,000 cars are listed at any moment, and this actor is built to reach all of them.

Input you pasteWhat comes back
blocket.se/mobility/search/car?... — any search, any filterOne row per matching car, across the whole result set
blocket.se/mobility/item/26253704 — a single adOne row for that car
blocket.se/mobility/dealer/9311124 — a dealer pageOne row per car in that dealer's inventory
Nothing at allEvery car on Blocket

Pure HTTP. No browser, no headless Chrome, no third-party bypass service. Blocket ships its data inside its own server-rendered pages, and this actor reads it there.


Why this is not a normal listing scraper

Blocket answers any single search with at most 50 pages of 49 ads. That is a hard ceiling of 2,450 rows per query, and it arrives with no error, no warning, and no marker in the response. Point a conventional crawler at "all cars" and it returns 2,450 of 144,000 and reports success.

This actor measures the size of your query first, then splits it into price ranges — halving, and halving again — until every piece fits under the ceiling. On the full Swedish car market that currently means 127 partitions planned from 255 counting queries, none of them touching the wall.

The split points are measured at run time, never hardcoded. A fixed ladder of price bands is only correct for the market it was measured against; the day the inventory shifts, one band crosses the ceiling and starts losing its tail with nothing in the log to say so.

Small runs skip all of that. Blocket lists newest first, so a run that wants 2,000 cars or fewer reads them straight off the first pages of your search: 60 cars from the whole market take two page loads and a few seconds.


How it works

How the Blocket scraper reaches every car

The run measures your query, plans the partitions, then walks each one. Ads seen while measuring are kept rather than re-fetched, and everything is deduplicated by ad ID, so a car that appears in two partitions is still one row.

At the end the actor compares what Blocket reported against what it actually collected and writes the difference into the log. Blocket's own count moves while a crawl runs — ads go up and come down by the minute — so a small delta is normal and the actor says so instead of pretending to a number it cannot guarantee.


Input

FieldTypeRequiredNotes
startUrlsarraynoSearch, ad or dealer URLs. Empty means every car on Blocket.
dealerOrgIdsarraynoDealer org IDs; each expands to that dealer's whole inventory.
detailLevelenumnobasic, full (default) or fullDealer. See below.
includePhonebooleannoResolve the number behind each ad's phone button. Default false.
maxItemsintegernoStop after this many cars. Default 1000. Up to 2,000 come straight from the newest results.
onlyNewbooleannoReturn only ads earlier runs did not return. For scheduled runs. Default false.
monitorIdstringnoNames the onlyNew memory. Empty means one memory per exact list of URLs.
compareToMarketbooleannoAdd each car's market value from similar live listings. Default false.
onlyBelowMarketBySekintegernoReturn only cars at least this many SEK below market, e.g. 10000.
onlyBelowMarketByPctintegernoReturn only cars at least this many percent below market, e.g. 10.
minDealConfidenceenumnomedium (default) or high: how sure a below-market match must be.
includeRedFlaggedbooleannoKeep below-market cars whose ad mentions damage, defects or parts only. Default false.
telegramBotTokenstringnoYour bot's token (stored encrypted). Sends each returned car to Telegram.
telegramChatIdstringnoThe chat, group or channel the alerts go to.
maxTelegramAlertsintegernoAlerts per run before the rest are summed up in one message. Default 50.
fullCoveragePassbooleannoSecond sweep to catch cars listed without a price. Default false.
safePartitionCapintegernoSplit anything above this. Default 2000.
partitionConcurrencyintegernoCounting queries in flight while planning. Default 5.
maxConcurrencyintegernoParallel requests while scraping. Default 10.
proxyobjectnoOptional. Blocket serves this actor without one.

Detail levels

LevelExtra requests per carWhat it adds
basicnone~35 fields straight from the search results: price, mileage, VIN, plate, coordinates, images, dealer name
full1Description, equipment list, battery capacity, colour, registration date, inspection dates, previous owners, seller's street address
fullDealer1 + one per dealerDealer website, email, switchboard number and postal address, fetched once per dealer and cached

basic is dramatically cheaper and already carries most of what a pricing or inventory analysis needs. Reach for full when you want the description, the equipment or the EV fields.

Example input

{
"startUrls": [
"https://www.blocket.se/mobility/search/car?fuel=4&dealer_segment=2&sales_form=1"
],
"detailLevel": "fullDealer",
"includePhone": true,
"maxItems": 5000
}

That reads every used electric car sold by a business. Any filter Blocket's own interface offers works in the URL — price_from, price_to, year_from, mileage_to, body_type, transmission, wheel_drive, exterior_colour, location and the rest are passed through untouched.


Monitor new listings

Put the actor on a schedule with onlyNew: true and every run returns only the cars published since the previous one. On a Sunday evening Blocket gets about two new car ads a minute, so a run every few minutes usually reads one or two search pages.

{
"startUrls": ["https://www.blocket.se/mobility/search/car?price_to=150000&dealer_segment=1"],
"onlyNew": true,
"detailLevel": "full",
"maxItems": 500
}

How it behaves:

  • The first run sets the starting point. It returns the newest cars up to maxItems. From then on, a run returns only ads published after that.
  • Nothing is charged twice. The actor remembers every ad it returned and skips it, including an old ad the seller bumps back to the top.
  • Runs stop early. Paging stops as soon as the results are older than where the last finished run started, so a quiet interval costs one or two page loads. With maxItems above 2,000 the search is still split first, and each piece stops after its first page.
  • Nothing gets lost when a run is cut short. If a run stops at maxItems, crashes or is aborted, the next run reads back down to the old starting point and returns what was missed. The log warns when runs keep hitting maxItems; raise it or run more often.
  • Results come newest first. A sort= in your URL is replaced for monitoring runs, since the actor has to read newest first to know where to stop.
  • The memory lives in your account, in a key-value store named blocket-scraper-monitor, one record per list of URLs. Editing the URL list starts a new baseline; set monitorId to keep one memory across edits, or to run two schedules over the same search. Ads are remembered for 90 days.

One limit: an older ad that starts matching your filters later, for example after a price cut brings it under your price_to, is not new and is not returned.


Market comparison and below-market deals

Turn on compareToMarket and every car gets a market value: what similar cars on Blocket are asking right now.

  • Comparables come from Blocket's own make and model list, not a text search, so a V60 is compared with V60s and never with XC60s. Fuel, gearbox and new/used always match.
  • The closest group with enough cars wins. First the same year, trim word (D4, Long Range, 320d), seller type and mileage within 20%; then each condition is relaxed in turn, down to year ±1 at any mileage. marketMatch says which group was used.
  • Each comparable is adjusted to this car's mileage along the model's own price-per-km slope, so a 330,000 km car is not valued against 230,000 km ones.
  • Every estimate shows its evidence: how many cars it rests on, their price spread, a high / medium / low confidence, and the five comparables closest in mileage with their links.

On 150 fresh listings, the high estimates had a median gap of −2.9% to the asking price and 97% of them landed within ±20%.

Set onlyBelowMarketBySek and/or onlyBelowMarketByPct to get only the cheap ones:

{
"onlyNew": true,
"onlyBelowMarketBySek": 10000,
"onlyBelowMarketByPct": 10,
"minDealConfidence": "high",
"detailLevel": "full"
}

A car is valued from its search result first, so one that isn't a deal costs no ad-page request and is never charged as a result. A below-market match needs at least five comparables and medium confidence (or high, if you ask for it). With a threshold set, maxItems limits how many cars are checked, not how many come back.

Cheap for a reason. Below-market cars whose title or ad text says motorfel, växellådsfel, startar ej, körförbud, reservdelar, krockskadad, leasingövertag, endast export and the like, or whose price is under 35% of market, are dropped unless you set includeRedFlagged. Every row carries a redFlags list either way. The ad text is only read at detail level full; at basic only the title and trim line are checked.

These are asking prices. Blocket publishes nothing about what cars sell for, so read marketValue as "what the market is asking", not "what it will sell for".


Telegram alerts

Give the actor a bot token and a chat id and every car a run returns arrives in Telegram as a photo with year, mileage, price, the market comparison and the link. Combined with onlyNew on a schedule and a below-market threshold, that is a deal alert: a message only when a new car is listed cheap.

  1. Message @BotFather on Telegram, send /newbot, and copy the token into telegramBotToken (the field is encrypted).
  2. Send your new bot any message, or add it to your group. Get the chat id from @userinfobot (a person) or from the group's settings (groups start with -100).
  3. Put the id in telegramChatId.

The actor checks the token and chat before the crawl and says in the log if either is wrong. It keeps to Telegram's limits (about one message a second to a person, twenty a minute to a group), waits when Telegram asks it to, and stops at maxTelegramAlerts with one closing message that counts the rest and links to the run.


Output schema

One row per car, 89 columns in a fixed order. Fields a run did not ask for come back as null rather than disappearing, so a CSV keeps the same shape from run to run.

{
"adId": "26253704",
"adUrl": "https://www.blocket.se/mobility/item/26253704",
"title": "Tesla Model X",
"make": "Tesla",
"model": "Model X",
"modelSpecification": "100D Long Range 6-sits *MOMS* 423hk",
"year": 2017,
"firstRegistration": "2017-06-13",
"bodyType": "SUV",
"exteriorColor": "Grå",
"price": 308900, // SEK, including VAT
"priceExVat": 247120, // where the seller marked it VAT-deductible
"currency": "SEK",
"marketValue": 331400, // with compareToMarket: median of similar live listings
"priceVsMarketSek": -22500, // negative = cheaper than the market
"priceVsMarketPct": -6.8,
"marketComparables": 9,
"marketConfidence": "high",
"marketMatch": "same model, fuel and gearbox, företag sellers, year 2016-2018, mileage ±20%, adjusted to 147290 km",
"marketSpreadPct": 11.4,
"marketListingsCount": 61,
"marketComparableSample": [{ "adUrl": "https://www.blocket.se/mobility/item/…", "price": 329900, "year": 2017, "mileageKm": 151200, "dealerSegment": "Företag" }],
"redFlags": [],
"mileage": 14729, // Scandinavian miles, as Blocket reports it
"mileageUnit": "SCANDINAVIAN_MILE",
"mileageKm": 147290, // converted — one mil is ten kilometres
"previousOwners": 10,
"fuel": "El",
"transmission": "Automatisk",
"wheelDrive": "Fyrhjulsdrift",
"enginePowerHp": 423,
"batteryCapacityKwh": 100, // a real structured field, not parsed out of the title
"drivingRangeKm": 435,
"rangePerKwh": 4.4,
"chargingCosts": { "home_charging": { "cost_pr_km": 0.41 }, "monthly_savings": { "monthly_amount": 780 } },
"registrationNumber": "YGT452",
"chassisNumber": "5yjxcce29hf045288",
"inspectionLast": "2026-03-19",
"inspectionNext": "2027-03-31",
"description": "Tesla Model X 100D AWD, 423 hk, 6-sits (2017)…",
"equipment": ["ABS-bromsar", "Backkamera", "Digitalt mätarhus", "…47 entries"],
"imageUrls": ["https://images.blocketcdn.se/dynamic/1280w/item/26253704/…"],
"imageCount": 19,
"sellerStreet": "Finspångsgatan 37",
"sellerZip": "16353",
"sellerCity": "Spånga",
"latitude": 59.39018,
"longitude": 17.87464,
"orgId": "9311124",
"organisationName": "Cederfeldts Bil",
"dealerSegment": "Företag",
"adPhoneNumber": "073-518 06 90", // behind the ad's phone button
"adContactPhone": "+46735180690", // the ad's own contact block
"dealerPhone": "073-518 06 90", // the dealer's profile page
"adContactEmail": "sulle@cederfeldtsbil.se",
"dealerEmail": "info@cederfeldtsbil.se",
"dealerWebsite": "http://www.cederfeldtsbil.se/",
"publishedAt": "2026-09-01T12:18:41.000Z",
"updatedAt": "2026-09-02T13:33:46.860Z",
"scrapedAt": "2026-09-02T15:06:30.241Z"
}

Three phone numbers, three columns

Blocket exposes a seller's number in three places and they genuinely disagree. On one Porsche Center Göteborg listing the phone button returned 031-361 83 72, the ad's contact block held +46313855500, and the dealer's own profile page said 031-385 55 00. Each gets its own column, labelled by where it came from, so you can decide which one your use case wants rather than having the actor decide for you. The same applies to email.


Pricing

Billed for work actually performed, so a cheap run stays cheap.

EventCharged whenRate
ResultEach car row$0.80 / 1,000
Ad detailAn ad page is opened (full and above)$0.50 / 1,000
Dealer profilePer unique dealer, not per row$0.002 each
Phone numberA number is actually returned$0.60 / 1,000
Market valuationA car is valued against live comparables (from 11 Oct 2026)$5 / 1,000
Telegram alertAn alert is delivered to your chat (from 11 Oct 2026)$3 / 1,000

Which works out to roughly $0.80 per 1,000 at basic, $1.30 at full, and about $1.86 with phone numbers switched on.

Nothing is charged for the counting queries that plan the partitions, for search pages, for retries, or for a phone lookup that comes back empty — around 7% of ads expose no number and those are free. A dealer with 200 cars in the run is charged once, not 200 times.

Market comparison and Telegram alerts are free until 11 October 2026. After that, a car that can't be valued (too few comparables) is not charged, a car turned away by a below-market threshold is charged for its valuation but not as a result, and failed alerts and the closing summary message are free.


What makes this richer than a generic listing scraper

CapabilityTypical scraperThis actor
Result-set sizeFirst 2,450 rows, silentlySplits the query until the whole set is reachable
Split pointsHardcoded price bandsMeasured at run time, so they survive a shifting market
Coverage reporting"Finished"Reported vs collected, delta written to the log
MileageRaw Blocket numberRaw value, unit, and kilometres — no factor-of-ten trap
Battery capacityParsed out of the title textBlocket's own structured battery_capacity field
Seller contactOne phoneThree phone sources and two email sources, each labelled
ImagesFirst photo, default sizeEvery photo at 1280px, the largest the CDN serves
BrowserOften headless ChromePure HTTP

Notes & limitations

Battery capacity is optional on Blocket. It is a real structured field, not something parsed out of the listing title, but sellers fill it in for only part of the inventory — roughly 40–45% in sampling. Expect nulls, and do not treat a null as "no battery data exists".

About 7% of ads expose no phone number. The number is served against a token that ships with the ad page, and some ads carry no token. Those rows get adPhoneNumber: null. That is Blocket withholding the number, not a failed request.

Cars listed without a price need the extra pass. The partitioner splits on price, so a car with no price is invisible to it — currently about 25 cars out of 144,000, or 0.02%. The actor detects this and says so in the log. Set fullCoveragePass: true to sweep a second axis and pick them up; it roughly doubles search-page traffic, and per-ad requests are deduplicated so those are not repeated.

A whole-market run costs real money and needs the cost limit raised. All ~144,000 cars comes to roughly $115 at basic, $187 at full, and around $268 with phone numbers on. Apify stops a run the moment it reaches the maximum-cost setting on that run, and it stops mid-crawl with no warning — a validation run of this actor was cut at 50,350 rows exactly that way. Raise the limit before starting a whole-market crawl, or keep the scope down with maxItems or a filtered search URL. A single price band or one dealer's inventory costs cents.

Mileage is in Scandinavian miles. Blocket's mileage is mil, where one mil is ten kilometres. Both the raw value and mileageKm are in the output. Using the raw number as kilometres puts you off by a factor of ten.

Swedish values are not translated. fuel, transmission, exteriorColor, bodyType and the equipment list come back as Blocket writes them — El, Automatisk, Grå. Translating them would mean guessing at a mapping and losing the original.

Blocket's own total moves during a run. It shifted three times within an hour during testing. The actor logs reported-versus-collected rather than asserting they match, because asserting it turns ordinary listing churn into failed runs.


🤖 For AI Agents & LLM Apps

Purpose: structured car listings from Blocket.se, Sweden's largest classifieds site. One row per car.

Minimal tested input:

{ "startUrls": ["https://www.blocket.se/mobility/search/car?fuel=4"], "detailLevel": "basic", "maxItems": 100 }

Key output fields: adId, adUrl, title, make, model, modelSpecification, year, firstRegistration, bodyType, exteriorColor, price, priceExVat, currency, mileage, mileageKm, previousOwners, fuel, transmission, wheelDrive, enginePowerHp, batteryCapacityKwh, drivingRangeKm, rangePerKwh, registrationNumber, chassisNumber, inspectionLast, inspectionNext, doors, seats, bootSizeLitres, weightKg, description, equipment, imageUrls, location, sellerStreet, sellerZip, sellerCity, latitude, longitude, orgId, organisationName, dealerSegment, adPhoneNumber, adContactPhone, dealerPhone, adContactEmail, dealerEmail, dealerWebsite, publishedAt, updatedAt, scrapedAt.

Behaviours worth knowing:

  • Billing is per row plus per unit of extra work: opening an ad, fetching a dealer profile, resolving a phone number. Partition planning, search pages, retries and empty phone lookups are free.
  • detailLevel: "basic" needs no per-ad request and is the cheapest way to survey the market.
  • mileage is in Scandinavian miles; use mileageKm for kilometres.
  • batteryCapacityKwh and adPhoneNumber are frequently null — that is source data, not failure.
  • Every field is present on every row, null when unknown, so the shape is stable.
  • Swedish enum values are not translated.
  • A capped run (maxItems reached) says so in the log and skips the coverage comparison.
  • A whole-market crawl is ~$115 at basic and ~$187 at full. Raise the run's maximum-cost setting first, or it aborts part-way through.

⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Blocket, Schibsted, Vend, or any of their subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper extracts only publicly visible data from Blocket.se — car listings, dealer profiles and the contact details Blocket itself shows to any logged-out visitor. No login, no CAPTCHA solving, no API-key forgery, no private-endpoint probing.

Users are responsible for:

  • Complying with Blocket.se's Terms of Service
  • Following GDPR and your jurisdiction's data-protection laws when storing or processing seller contact details, registration plates and VINs
  • Not contacting sellers listed in scraped data without a lawful basis for doing so
  • Not republishing scraped data in a way that competes commercially with Blocket
  • Honouring any opt-out signals on the source pages

Registration plates and chassis numbers are personal data in many jurisdictions when they can be linked to an individual. Treat them accordingly.


SEO Keywords

blocket scraper, scrape blocket, blocket.se scraper, blocket car scraper, blocket bilar scraper, swedish car listings scraper, sweden used car data, blocket api, blocket mobility scraper, swedish car market data, blocket dealer scraper, blocket annonser scraper, used car price data sweden, swedish vehicle listings, blocket electric car scraper, sweden ev listings scraper, blocket elbil scraper, car dealer leads sweden, swedish car dealer contacts, vin scraper sweden, registration plate scraper sweden, blocket cheerio scraper, no-browser blocket scraper, apify blocket, blocket bulk export, swedish automotive market research, car pricing intelligence sweden, blocket inventory scraper, blocket bil data, nordic car listings scraper, blocket listing extraction