Artmajeur.com Artist & Artwork Scraper avatar

Artmajeur.com Artist & Artwork Scraper

Pricing

from $5.00 / 1,000 results

Go to Apify Store
Artmajeur.com Artist & Artwork Scraper

Artmajeur.com Artist & Artwork Scraper

Artmajeur.com artist & artwork scraper with real per-artist rollup stats (avg price, medium mix, sold count) from each artist's full catalog, plus delta mode.

Pricing

from $5.00 / 1,000 results

Rating

0.0

(0)

Developer

Artsiom Kunitsyn

Artsiom Kunitsyn

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

artmajeur-scraper

Scrapes both artworks and artist profiles from Artmajeur.com, including per-artist rollup stats (average price, medium mix, sold count, latest artwork) computed from the artist's full catalog β€” not a sample.

Contents

πŸ”‘ Key features

  • Two entity types, one Actor. Set entityType to artworks or artists β€” no need for two separate scrapers to build a full picture of an artist and their work.
  • Real per-artist rollup stats, not a sample. Average price, unique medium mix, sold-artwork count, and latest artwork are computed from an artist's entire catalog, enumerated via Artmajeur's own per-artist RSS feed (paginated to completion).
  • Delta mode built in. Every run classifies each item as new, changed, unchanged, or delisted against a persisted baseline β€” pay for what changed, not a full re-scrape every time.
  • Exhaustive when you ask for it. With no startUrls/artistUrls, the underlying discovery is the full site sitemap β€” every artwork (~3.1M), every artist (~108K) β€” but maxItems defaults to 50 (a fast preview, and what keeps an unconfigured run within Apify's automated 5-minute QA check), so clear it (null) for a real full crawl. Category/sub-category narrowing was built and removed: its URL path segments genuinely filter server-side, but the entire /en/artworks/* route sits behind an interactive Cloudflare challenge that no plain HTTP client can pass β€” confirmed across three independent networks (see Input and the FAQ).
  • A verified, trackable artist list. artistUrls lets you scrape exactly the artists you care about β€” each URL is checked against the real sitemap first (typos/removed artists are logged and skipped), and unlike a generic startUrls list, it gets its own persisted tracking scope: run the same list on a schedule and get real new/changed/delisted detection for just those artists.
  • Progress visible in the run log. Every ~10 items or ~20 seconds, the log reports how many items have been processed (with a known total for bounded runs), pushed, and errored, plus the observed rate β€” and for entityType: artists, a running count of artworks fetched across all rollups so far.
  • Confirmed-dead URLs are never re-fetched. A real run found 58% of a sitemap sample were already HTTP 410 Gone (genuinely deactivated/removed accounts still listed in Artmajeur's own sitemap) β€” every 410 is now persisted (per entity type, including artwork URLs found inside an artist's rollup) and skipped on every future run, no input needed to enable it.

πŸ“‹ Output

One dataset item per artwork or artist, depending on entityType β€” see .actor/dataset_schema.json for the full field list, or the Output tab's Artworks / Artists views for a readable table.

Example artwork record:

{
"source": "artmajeur",
"entity_type": "artworks",
"external_id": "artmajeur_16257",
"url": "https://www.artmajeur.com/serge-reynaud-art-of-flying/en/artworks/16257/aquila-nuvole",
"title": "Aquila Nuvole",
"artist_name": "Serge Reynaud (Art of Flying)",
"artist_url": "https://www.artmajeur.com/serge-reynaud-art-of-flying/en",
"category": "Sculpture",
"technique": "Sculpture",
"price": 16301,
"currency": "EUR",
"availability_status": "InStock",
"height_cm": 60.0,
"width_cm": 70.0,
"change_type": "new"
}

Example artist record:

{
"source": "artmajeur",
"entity_type": "artists",
"external_id": "samuel",
"url": "https://www.artmajeur.com/samuel",
"name": "Samuel Charmetant",
"country": "FR",
"city": "CLAPIERS",
"job_title": "Photographer",
"followers": 76,
"total_artworks": 42,
"sold_artworks": 5,
"avg_price": 340.5,
"mediums": "Photography",
"change_type": "new"
}

Results can be downloaded as JSON, CSV, or Excel from the Console's Output tab, or pulled via the Apify API/dataset endpoint.

Known gaps:

  • Artwork depth_cm is only populated when Artmajeur's own dimensions text uses the labeled "Height/Width/Depth" format β€” the bare compact format ("53x43 cm") never showed a third number live, and its two-number order (assumed Height x Width) still isn't independently confirmable from any other field on the page.
  • A sold artwork (availability_status: "Sold") always has price/currency as null β€” the page genuinely doesn't redisplay a price for sold items, confirmed against a real example.
  • price/currency (and the artist rollup's avg_price/sold_avg_price/latest_artwork_price) are native, unconverted values β€” Artmajeur geo-detects displayed currency by the requester's IP, so the same artwork can show different currencies depending on which IP/proxy scrapes it. The rollup's averaging assumes one currency across an artist's whole catalog (the common case) β€” it does not detect or convert mixed currencies.
  • No category/sub-category narrowing input β€” see Key features and the FAQ.

βš™οΈ Input

See .actor/input_schema.json for the full JSON schema.

ParameterTypeDefaultDescription
entityTypeStringartworksartworks or artists.
startUrlsArray of strings(none)Specific artist or artwork URLs to scrape directly, instead of discovering via the full site sitemap. Scope is always "custom", with no persisted tracking across runs β€” for persisted per-artist tracking, use artistUrls instead, which also checks each URL against the site's member sitemap.
artistUrlsArray of strings(none)Artists only. Paste artist URLs, one per line (a .txt file's contents paste in directly, no upload needed) to scrape exactly those artists + their artworks. Verified against the real member sitemap first (see verifyArtistUrls); gets its own persisted scope, so re-running the same list on a schedule gives real new/changed/delisted tracking for just those artists. Takes priority over startUrls.
verifyArtistUrlsBooleantrueWhen artistUrls is set, check each URL against the real sitemap first (~2 minutes, one full sitemap walk, regardless of list size) and skip any not found. Turn off to scrape the list unverified.
maxItemsInteger50Stop after pushing this many dataset items. Defaults to a fast, cheap preview (also what keeps an unconfigured run within Apify's automated 5-minute QA check β€” this actor paces requests to 1/sec, so an uncapped default run could never pass that check regardless of speed). A full crawl covers the entire site (millions of artworks, or the full ~108K-artist directory) β€” raise this or clear it (set to null) for that; note a capped run never updates the incremental baseline (see below), so any real tracking run needs this cleared.
modeStringautoauto (recommended): full scan on the first run, incremental after. full: always push every item and refresh the baseline. incremental: always push only new/changed items. Only a plain, unscoped sitemap crawl can detect delistings or update the baseline.
impersonateStringchrome (internal)curl_cffi TLS-impersonation target. Artmajeur's Cloudflare protection challenges plain requests, so this is set internally by default β€” override only if that stops working.
proxyConfigurationObject{"useApifyProxy": false}Apify Proxy config. Off by default β€” the sitemap/profile/detail pages this Actor relies on worked fine without one while building it.

πŸ§ͺ Input examples

Full artwork catalog scan (exhaustive, slow β€” every artwork's detail page is fetched; maxItems: null explicitly overrides the 50-item default):

{ "entityType": "artworks", "maxItems": null }

Bounded preview (the default β€” fast, but not a curated subset, just the first N artworks the sitemap yields):

{ "entityType": "artworks", "maxItems": 200 }

Full artist directory, with rollup stats:

{ "entityType": "artists", "maxItems": null }

A specific, tracked list of artists (verified against the sitemap, own persisted scope β€” maxItems: null so the whole list is scraped even if it's longer than the 50-item default):

{
"entityType": "artists",
"artistUrls": [
"https://www.artmajeur.com/samuel",
"https://www.artmajeur.com/serge-reynaud-art-of-flying"
],
"maxItems": null
}

Scheduled tracking run β€” full, uncapped run (maxItems cleared β€” required for the baseline to save and delistings to be detected):

{ "entityType": "artworks", "mode": "incremental", "maxItems": null }

πŸ”„ Incremental (delta) mode

Every run classifies each item as new, changed (price or availability moved, for artworks; catalog size/sold-count/avg-price moved, for artists), unchanged, or delisted, using a state baseline persisted in a named Apify Key-Value Store scoped to entityType.

  • mode: auto (default) β€” first run for a scope pushes everything (full); later runs push only new/changed/delisted (incremental).
  • A startUrls-scoped run is always partial and never updates the baseline. artistUrls is different: it's treated as a complete, closed universe (like a full sitemap crawl), so its baseline does get saved and delisted-detection does run β€” as long as no item hit a genuinely ambiguous error that run (a confirmed HTTP 410 doesn't count against this β€” see below; a timeout, 5xx, or parse error does, and skips the baseline-save/delisted-detection that run to avoid false "delisted" reports).
  • Every bounded run (startUrls or artistUrls) logs a quick "X new, Y already tracked, Z already known-dead" preview right after startup, before the full fetch loop begins β€” new/already-tracked is informational only (every URL is still fully fetched and classified regardless, real price/status-change detection isn't skipped for "already tracked" items); already-known-dead URLs genuinely are skipped, see below.
  • A URL confirmed permanently gone (HTTP 410) is recorded and never fetched again on any future run, regardless of mode or scope β€” logged distinctly from other errors. Doesn't count toward the baseline-save/delisted-detection gate above, since it's a trustworthy, already-understood outcome rather than an ambiguous failure.

Full design: ../../docs/incremental-mode.md.

πŸš€ How to scrape Artmajeur.com

  1. Open the Artmajeur Artist & Artwork Scraper in Apify Console and go to the Input tab.
  2. Pick entityType (artworks or artists).
  3. maxItems defaults to 50 (a quick preview) β€” clear it (set to null) for a full, uncapped run.
  4. Click Start.
  5. When the run finishes, browse results in the Output tab, or download as JSON/CSV/Excel, or fetch them via the API.
  6. To track over time instead of scraping once: create a Schedule with mode: auto β€” the first run does a full scan, every run after only bills what actually changed.

πŸ”— You might also like

  • SaatchiArt Artist & Artwork Scraper β€” the same entity-type/rollup-stats design pointed at a second, independent art marketplace, for expanding artist coverage or cross-referencing the same artist's presence and pricing across platforms.
  • Artsper Artist & Artwork Scraper β€” a third, independent art marketplace source, same design.

❓ FAQ

Is it legal to scrape Artmajeur.com? It's legal to collect publicly available marketplace data such as artwork listings, prices, and public artist profile information. Scrape it only with a legitimate purpose under GDPR.

How do I get only new/changed items? Use mode: auto (or incremental) on a schedule β€” see Incremental mode.

Why doesn't this Actor support filtering by category, price, style, subject, or country? Artmajeur's catalog/browse pages (/en/artworks/...) sit behind an interactive Cloudflare challenge β€” confirmed while building this actor across three independent networks (a home/office IP, a datacenter proxy, and Apify's own datacenter proxy group), all three blocked on that route while sitemap/profile/artwork-detail requests on the same sessions stayed open throughout. That's not a rate-limit issue pacing or a different IP can fix β€” it needs either a properly-provisioned unblocking proxy or browser automation, neither of which this Actor currently uses. Use maxItems for a bounded preview instead.

Search keywords

artmajeur scraper, art marketplace scraper, artist data scraper, artwork data scraper, art price data, art market analytics, art collector data feed