Artmajeur.com Artist & Artwork Scraper
Pricing
from $5.00 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
6 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
- Output
- Input
- Input examples
- Incremental (delta) mode
- How to scrape Artmajeur.com
- You might also like
- FAQ
๐ Key features
- Two entity types, one Actor. Set
entityTypetoartworksorartistsโ 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 each artist's own profile gallery (paginated to completion).
- Delta mode built in. Every run classifies each item as
new,changed,unchanged, ordelistedagainst 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) โ butmaxItemsdefaults 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(entityType=artists) 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 genericstartUrlslist, 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. - Full artwork detail for specific artists. The same
artistUrlsinput also works onentityType: "artworks"โ fetches every artwork for exactly those artists instead of the full sitemap. Pair with anentityType: "artists"+minSoldArtworksrun to first collect the artist URLs you want. - 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_cmis 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 hasprice/currencyasnullโ the page genuinely doesn't redisplay a price for sold items, confirmed against a real example. price/currency(and the artist rollup'savg_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.
| Parameter | Type | Default | Description |
|---|---|---|---|
entityType | String | artworks | artworks or artists. |
startUrls | Array 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. |
artistUrls | Array of strings | (none) | For entityType=artists: paste artist URLs, one per line (a .txt file's contents paste in directly, no upload needed) to scrape exactly those artists. 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. For entityType=artworks: fetches every artwork for exactly those artists instead of the full artwork sitemap (unverified). Takes priority over startUrls for artists; for artworks, startUrls still wins over this. |
verifyArtistUrls | Boolean | true | When 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. |
maxItems | Integer | 50 | Stop 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. |
minSoldArtworks | Integer | 0 | Artists only. Only push artist records with at least this many sold artworks (the sold_artworks rollup field) โ set to 1 to skip artists who've never sold anything. Artists are still fully tracked internally either way (delta baseline, delisted-detection); this only filters what's pushed to the dataset. |
mode | String | auto | auto (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. |
impersonate | String | chrome (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. |
proxyConfiguration | Object | {"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 }
Artists with at least one sold artwork only (skips the majority of artists who've never sold โ useful if you only care about active sellers):
{ "entityType": "artists", "minSoldArtworks": 1, "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 onlynew/changed/delisted(incremental).- A
startUrls-scoped run is always partial and never updates the baseline.artistUrlsis 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 (
startUrlsorartistUrls) 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
modeor 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.
๐ How to scrape Artmajeur.com
- Open the Artmajeur Artist & Artwork Scraper in Apify Console and go to the Input tab.
- Pick
entityType(artworksorartists). maxItemsdefaults to 50 (a quick preview) โ clear it (set tonull) for a full, uncapped run.- Click Start.
- When the run finishes, browse results in the Output tab, or download as JSON/CSV/Excel, or fetch them via the API.
- 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.
- Artfinder Artist & Artwork Scraper โ a fourth, independent art marketplace source, same design.
- Artsy Artist, Artwork & Gallery Scraper โ a fifth, independent art marketplace source, plus a genuine dealer/gallery angle (real represented-artist rollups per gallery) this collection doesn't otherwise have.
- Bluethumb Artist & Artwork Scraper โ a sixth, independent art marketplace source (Australia's largest), with real per-artist sold/available/total counts read from a single profile-page fetch, no rollup fan-out needed.
- Riseart Artist & Artwork Scraper โ a seventh, independent art marketplace source, built entirely on the site's own public GraphQL search API (no HTML scraping, no per-item detail fetch), with a real per-artist rollup (total artworks, avg price, for-sale vs. enquire-only split).
- Kunsthaus ARTES Artist & Artwork Scraper โ an eighth, independent art marketplace source (German gallery), with a real four-state availability signal (for sale, price-on-request, reserved, sold) read from the site's own schema.org microdata.
- Ars Mundi Artist & Artwork Scraper โ a ninth, independent art marketplace source (a sibling German gallery running the same underlying platform as Kunsthaus ARTES), also selling jewelry and decorative objects alongside paintings/sculptures.
- Artprice.com Artist & Artwork Scraper โ a tenth, independent art marketplace source, built on Artprice.com's own public unauthenticated JSON APIs (artist directory + current marketplace listings), with real per-artist rollup stats and multi-currency pricing (EUR/USD/GBP/CNY/BTC/ETH) on every artwork.
โ 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