1. 2scraper
  2. E-commerce & retail
  3. Catawiki
Open source · MITRuns with no key, proxy or account

Catawiki Scraper

Auction lots, bids, reserves, estimates and sellers from Catawiki — runs with no key, proxy or account.

  • Playwright
  • Selenium
  • Puppeteer
  • Scraping Browser API
  • JSON
  • CSV
catawiki-scraper
# Category listings
$ python3 playwright_scraper.py --url 'https://www.catawiki.com/en/c/333-watches' --pages 3 --format both --out watches
✓ 5 sample rows · 44 columns in sample_output.json
18Catawiki locales supported
4page kinds: listing, auction, lot, auctions index
130lots in one auction-page response (measured Sep 2026)
0keys, proxies or accounts needed
Available Catawiki scrapers

What the Catawiki scraper collects

Scrapes Catawiki auction lots from category listings, search results, whole auction pages and single lot pages, plus the auctions index as a work list. Each lot becomes one row with its bid state, reserve flags, seller and timing, written to JSON or CSV with a run sidecar.

Category listings

Input: A category URL

24 lots per page with current bid, bid kind, reserve flags, favourite count and the card's time-left text.

Search results

Input: A search URL

The same lot rows for a keyword search; a query that matched nothing is detected rather than parsed into suggested lots.

Whole auction

Input: An auction URL

Every lot of one auction in a single response, with the auction's own absolute close time and status.

Single lot

Input: A lot URL

One lot in full: estimate, brand, seller score and country, specifications and absolute bidding start and end times.

Auctions index

Input: The auctions index URL

One thin row per auction (id, url, title, ends text, slug, locale) to feed back in as auction URLs.

Quick start

From zero to Catawiki data in 3 steps

  1. Install

    Clone the repository and install one browser engine. Python 3.9+.

    $ git clone https://github.com/2scraper/catawiki-scraper.git && cd catawiki-scraper
    $ pip install -r requirements.txt -r requirements-playwright.txt
    $ python -m playwright install chromium
  2. Run a scraper

    Pick what you need and run it. Every flag is documented in the README.

    $ python3 playwright_scraper.py --url 'https://www.catawiki.com/en/c/333-watches' --pages 3 --format both --out watches
  3. Get structured data

    Rows land in JSON or CSV (--format), with a .meta.json sidecar recording status, pages fetched and why the run stopped.

Output

Catawiki data fields

44 columns per row in a predictable schema. The most useful ones:

FieldWhat it holds
skuCatawiki lot id
titleLot title as listed
priceBid amount; what it means is given by bid_kind
currencyCurrency of the price (EUR on every locale)
bid_kindcurrent, final, starting, or null when no price is published
bid_countNumber of bids seen (a floor: the site returns the last ten)
reserve_price_setWhether the lot has a reserve price
reserve_price_metWhether the reserve has been reached
soldWhether a closed lot actually sold
buy_nowBuy-now price, where offered
favorite_countFavourites, read from the rendered card
estimate_minLow end of the expert estimate (lot mode)
estimate_maxHigh end of the expert estimate (lot mode)
bidding_end_atAbsolute bidding end time (lot mode)
auction_idId of the auction the lot belongs to
seller_scoreSeller feedback score (lot mode)
[
  {
    "source": "catawiki.com",
    "scraped_at": "2026-09-10T22:07:38.735190+00:00",
    "url": "https://www.catawiki.com/en/l/106438305-tecnotempo-professional-automatic-japan-movt-20…",
    "sku": "106438305",
    "title": "Tecnotempo - Professional Automatic - Japan Movt - 200M W.R - No reserve price - TT.200…",
    "brand": null,
    "price": 102.0,
    "currency": "EUR",
    "original_price": null,
    "discount_pct": null,
    "rating": null,
    "review_count": null,
    "in_stock": null,
    "image_url": "https://assets.catawiki.nl/assets/2025/6/26/6/2/0/620fcdff-7d24-4578-afcc-e9c918d6d218.jpg",
    "category": "333-watches",
    "price_source": "next_data+dom",
    "page": 1,
    "position": 1,
    "bid_kind": "current",
    "bid_status_text": "Current bid",
    "bid_count": null,
    "bid_count_is_floor": null,
    "next_min_bid": null,
    "time_left_text": null,
    "bidding_start_at": "2026-09-04T16:00:00+00:00",
    "bidding_end_at": null,
    "reserve_price_set": false,
    "reserve_price_met": null,
    "sold": null,
    "buy_now": 650.0,
    "has_free_shipping": null,
    "favorite_count": 25,
    "subtitle": "Automatic - Steel",
    "estimate_min": null,
    "estimate_max": null,
    "auction_id": "1263899",
    "auction_title": null,
    "auction_close_at": null,
    "auction_status": null,
    "seller_id": null
  },
  {
    "source": "catawiki.com",
    "scraped_at": "2026-09-10T22:07:38.736067+00:00",
    "url": "https://www.catawiki.com/en/l/105206040-romain-jerome-titanic-dna-no-reserve-price-part…",
    "sku": "105206040",
    "title": "Romain Jerome - Titanic DNA - No reserve price - Parts of the Titanic - BRAND NEW - Men…",
    "brand": null,
    "price": 2401.0,
    "currency": "EUR",
    "original_price": null,
    "discount_pct": null,
    "rating": null,
    "review_count": null,
    "in_stock": null,
    "image_url": "https://assets.catawiki.nl/assets/2024/3/29/b/4/a/b4abbfe6-ee79-4caf-9f91-25ec587e3237.jpg",
    "category": "333-watches",
    "price_source": "next_data+dom",
    "page": 1,
    "position": 2,
    "bid_kind": "current",
    "bid_status_text": "Current bid",
    "bid_count": null,
    "bid_count_is_floor": null,
    "next_min_bid": null,
    "time_left_text": null,
    "bidding_start_at": "2026-09-04T10:00:00+00:00",
    "bidding_end_at": null,
    "reserve_price_set": false,
    "reserve_price_met": null,
    "sold": null,
    "buy_now": null,
    "has_free_shipping": null,
    "favorite_count": 73,
    "subtitle": "Automatic - Steel",
    "estimate_min": null,
    "estimate_max": null,
    "auction_id": "1263549",
    "auction_title": null,
    "auction_close_at": null,
    "auction_status": null,
    "seller_id": null
  }
]

First 2 of 5 rows from a real run — sample_output.json. Long values shortened here.

Built for Catawiki

Handles what breaks naive Catawiki scrapers

Bid meaning made explicit

price can be a live bid, a final bid or an unbid starting price; bid_kind says which, and sold separates a hammer price from a lot that closed below its reserve.

Null price means reserve, checked

Every blank price is a reserve lot (57 of 57 in captures, Sep 2026); the suite and the canary assert that a null price always carries reserve_price_set.

The 100-page clamp detected

Catawiki answers any page past 100 with page 100 again. Page planning is capped at 100, and the run reports how much of the catalogue lies beyond it instead of claiming completeness.

Wrong-looking fields avoided

The payload's favoriteCount is 0 everywhere, so the count is read from the rendered card; lot-page carousels of similar lots are never read as the lot's own price.

Everything built in

Scraping infrastructure included

The same tested core runs every 2scraper repository, so the hard parts work the same way on every site.

CAPTCHA handling

Detects the challenge a page really serves and, with a 2Captcha key, solves it only when it blocks the data — a capped number of solves per page.

Proxy rotation

Single proxy or a pool from a file, rotated on blocks with a fresh browser per exit. Credentials stay out of argv and logs.

Fingerprints

Optional complete device identity from the 2Captcha Fingerprint API — user agent, client hints, locale and timezone that agree with each other.

Scraping Browser API

Point --cdp-endpoint at a managed Chromium with its own exit country — no browser infrastructure to run yourself.

Honest run metadata

Every run writes a .meta.json sidecar and distinct exit codes: complete, blocked, empty and partial are never confused, and a failed run never overwrites good data.

Diff two runs

diff_runs.py compares two complete Catawiki snapshots by id — new, removed and changed rows for monitoring.

Use cases

What teams do with Catawiki data

Hammer-price research

Collect final bids on closed lots, with sold and reserve flags, to build price histories for watches, art or collectibles.

Live auction monitoring

Walk the auctions index, then each auction page, to track current bids and close times across every lot at once.

Estimate vs. result analysis

Compare expert estimate_min and estimate_max from lot pages against where bidding ended.

Seller and category tracking

Follow seller scores, countries and per-category lot volume across Catawiki's 18 locales.

Access & pricing

Free to run. Pay only for what the site requires.

Runs with no key, proxy or account

No key, proxy or account: a local headful Chrome on an ordinary connection returned 24 of 24 lots with full price coverage (Sep 2026). The catch is the browser mode, not the address — the site refuses headless browsers from residential and datacentre exits alike, so --headful is the default. The Scraping Browser API adds a remote browser with a chosen exit country and no local browser to run; proxies add volume from many addresses, and fingerprints a consistent device identity. Captcha solving is wired in, but no challenge was met in 19 captures.

Optional 2Captcha services — captcha solving, the Scraping Browser API, residential proxies and fingerprints — work behind one key.

Good to know

  • Category and search listings are capped by the site at 100 pages.
  • bid_count is a floor: the site returns only the last ten bids.
  • brand, estimates and absolute bidding times are filled only in --mode lot; rating and review_count are always null.

2scraper vs. hosted scraper APIs

2scraperTypical hosted API
CodeOpen source, MIT — read and patch itClosed
CostFree; optional services billed only when usedSubscription or per request / per result
Runs onYour machine, server or CIThe vendor's infrastructure
OutputJSON/CSV files + run metadataAPI responses
When the site changesFix it yourself or open an issue / PRWait for the vendor
FAQ

Catawiki scraper FAQ

Which output formats are supported?

JSON, CSV or both (--format both), with the same columns in the same order, plus a <out>.meta.json sidecar recording status, stop reason and which pages failed.

Why does it run a visible (headful) browser by default?

Measured in Sep 2026, Catawiki refused every headless browser with 403 regardless of IP, while headful Chrome was served. --headless is still accepted but reports exit 3 today.

Do I need a proxy or a 2Captcha key?

No. A proxy does not get a headless browser in, and no captcha was rendered to an anonymous visitor. Paid products help with volume, exit country and running no local browser.

Why are some prices null?

A null price means the lot's reserve has not been met and the site publishes no bid amount; such rows always carry reserve_price_set: true.

How many pages can I scrape from one category?

Catawiki serves at most 100 pages of 24 lots. For full coverage, walk the auctions index with --mode auctions and scrape each auction page, which carries all its lots at once.

Is scraping Catawiki legal?

The scraper reads public listing pages only — no login, no bidding. It is public data; follow the site's terms and the law where you operate.