Drouot Scraper - Auction Lots, Sales & House Contacts
Pricing
$1.80 / 1,000 per row returneds
Drouot Scraper - Auction Lots, Sales & House Contacts
From $1.80 per 1,000 rows, no start fee. drouot.com: 214,444 lots across 809 upcoming sales from 364 auction houses. Every lot, sale and house row carries the auctioneer's email, phone and address, plus company registration and VAT numbers. Filter by category, search, country, sale type or estimate.
Pricing
$1.80 / 1,000 per row returneds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 hours ago
Last modified
Categories
Share
Drouot Scraper — auction lots, sales and auction-house contacts
drouot.com is the marketplace for the Hôtel Drouot in Paris and the partner auction houses that catalogue through it. This actor exports it three ways, and every single row carries the auction house's email, telephone and street address — so a lot list is also a lead list.
Measured on the live site on 2026-09-18, through the Apify proxy, by walking every list to its last page:
| measured | |
|---|---|
| Upcoming sales on the board | 809 distinct (the source's own counter said 836 at the same moment — see Honest limits) |
| Auction houses running them | 364 distinct |
| Lots in those catalogues | 214,576 (sum of the source's own per-sale lotCount) |
| Lot rows actually harvested in this measurement run | 62,440 (page 1 of every sale) |
| Lot URLs in Drouot's own sitemap | 201,820 |
| Countries represented | 27, from France (491 sales) to Uruguay (1) |
| Cost of the whole contact-bearing sale calendar | 17 requests |
What one row is
Pick Row type in the input.
lots — one row per lot (the default)
Lot number, title, description, estimates, live bid, buyer's premium, photos — plus the whole
sale and the whole auction house on the same row. This is a real row from the verified run
(fixtures/lot_detail.json, with Add the auction house registry block on):
{"recordType": "lot","lotId": 34888742,"lotUrl": "https://drouot.com/en/l/34888742-a-set-of-five-porcelain-coffee-cups-and-six-saucers-with","lotNumber": 780,"title": "A set of five porcelain coffee cups and six saucers with white bases and a blue monochrome design.","description": "A set of five porcelain coffee cups and six saucers with white bases and a blue monochrome design.","descriptionIsTruncated": false,"originalDescription": "Ensemble de cinq tasses à café et six sous tasses en porcelaine à fond blanc et décor en camaïeu bleu.","categoryIds": [632],"categories": ["Sets of tableware"],"categoryPath": "Sets of tableware","attributes": null,"lowEstimate": 10,"highEstimate": 20,"estimateRange": "10-20","currentBid": null,"nextBid": 10,"startingPrice": 10,"hammerPrice": null,"tenderingAmount": null,"reserveNotReached": false,"displayStartingPrice": true,"biddingStartsAt": "2026-09-17T09:00:00.000Z","biddingEndsAt": "2026-09-19T09:00:00.000Z","forProsOnly": false,"transportSize": null,"censorship": null,"imageUrl": "https://cdn.drouot.com/d/image/lot?size=fullHD&path=840/183595/639065a658d4a5249eac834799b23490","images": ["https://cdn.drouot.com/d/image/lot?size=fullHD&path=840/183595/639065a658d4a5249eac834799b23490","https://cdn.drouot.com/d/image/lot?size=fullHD&path=840/183595/4e7571db5c0f22f15dae9672a41c13f5","https://cdn.drouot.com/d/image/lot?size=fullHD&path=840/183595/926904b9ff7a85f0a7bd8aad6f8f7635"],"imageCount": 3,"saleId": 183595,"saleUrl": "https://drouot.com/en/v/183595-tableware-jewelry-designer-items","saleTitle": "Tableware, jewelry, designer items","saleDate": "2026-09-19T09:00:00.000Z","saleStatus": "CREATED","saleType": "LIVE","saleTimeZone": "Europe/Paris","currency": "EUR","buyerPremiumPercent": 24,"platformFeesIncluded": false,"registrationDeadline": "2026-09-20T09:00:00.000Z","houseId": 840,"houseName": "Étampes Enchères","houseUrl": "https://drouot.com/en/auctioneer/840/etampes-encheres","houseEmail": "svvetampesencheres@yahoo.fr","housePhone": "+33164940233","houseLifetimeLotCount": 27204,"houseMemberSince": "2022-05-21T12:30:00.000Z","houseLogoUrl": "https://cdn.drouot.com/d/CP/logo?size=fullHD&cpId=/840","street": "Route de la Ferté Alais, carrefour D191 et D837","postalCode": "91150","city": "Morigny-Champigny","countryId": 75,"country": "France","atHotelDrouot": false,"houseRegisterNumber": "44281540300021","houseAgreementNumber": "2002-292","houseVatNumber": "FR84442815403","houseWebsite": "https://www.etampesencheres.fr","houseDrouotCertified": false,"scrapedAt": "2026-09-18T19:41:12.004Z"}
sales — one row per auction (809 upcoming)
The same contact list at 1/77th the row count: sale title, date, status, type, lot count, buyer's premium, registration deadline, catalogue PDF, terms of sale, and the house's full contact block. The whole calendar costs 17 requests.
auctionHouses — one row per house (364)
The prospect list. Everything above plus the company registration number, the French agrément number (the authorisation an opérateur de ventes volontaires must hold under Code de commerce L321-4), the VAT number, the house's own website, its named auctioneers, and its published hammer prices.
Measured field fill
Every percentage below is a count over rows this actor actually produced on 2026-09-18, not an
estimate. A field is "filled" only if it is a non-empty value: 0, "", "N/A" and "-" are not.
Sale rows — n = 809 (the whole live board)
| field | fill | field | fill |
|---|---|---|---|
saleId saleUrl saleTitle saleDate | 100% | houseEmail | 100% (809/809) |
saleStatus saleType currency | 100% | housePhone | 98.9% (800/809) |
buyerPremiumPercent | 100% | street | 99.8% (807/809) |
registrationDeadline | 100% | postalCode city | 98.0% |
saleTimeZone platformFeesIncluded | 100% | countryId | 100% |
houseId houseName houseUrl | 100% | country (resolved) | 100% |
coverImageUrl | 99.4% | atHotelDrouot | 100% |
saleDescription | 85.3% | lotCount | 80.6% |
houseShippingOffer | 22.6% | venueName | 24.4% |
catalogPdfUrl | 8.8% | externalCatalogUrl | 5.7% |
virtualTourUrl | 0.4% | saleAnnouncement | 0% on this route (10.7% on the sale page) |
A second, independent census of 215 sales read from their own sale pages (not the board) gave
houseEmail 100%, housePhone 99.5%, street 99.5%, saleTerms 100%, lotCount 100%,
saleDescription 90.7%, saleAnnouncement 10.7%, catalogPdfUrl 14.0%.
Lot rows — n = 62,440 (page 1 of all 809 sales)
| field | fill | field | fill |
|---|---|---|---|
lotId lotUrl lotNumber title | 100% | houseEmail | 100% (62,440/62,440) |
description | 100% | housePhone | 98.6% |
biddingEndsAt currency | 100% | street | 99.7% |
buyerPremiumPercent | 100% | postalCode city | 97.6% |
saleId saleTitle saleDate saleType | 100% | country | 100% |
imageUrl images | 99.8% | registrationDeadline | 100% |
lowEstimate | 93.8% | highEstimate | 90.0% |
nextBid | 58.2% | attributes | 24.0% |
currentBid | 3.4% overall — 22.0% of lots in ONLINE sales, 0% everywhere else | descriptionIsTruncated = true | 5.8% |
biddingStartsAt | 5.4% | transportSize | 4.4% |
hammerPrice | 0% on the forward board — see Honest limits | tenderingAmount | 0.4% |
Sliced by sale type, because bidding data only exists where bidding is open:
| sale type / status | lots | currentBid | lowEstimate | highEstimate |
|---|---|---|---|---|
| LIVE / CREATED | 50,031 | 0.0% | 94.6% | 90.5% |
| ONLINE / IN_PROGRESS | 9,633 | 22.0% | 88.9% | 86.8% |
| CATALOGUE / CREATED | 2,476 | 0.0% | 100.0% | 96.0% |
| LIVE / IN_PROGRESS | 300 | 0.0% | 66.0% | 66.0% |
Lot rows read from each lot's own page — n = 299 (fetchLotDetails)
originalDescription 100% · categoryIds 90.0% · categories 89.3% · startingPrice 93.0% ·
houseMemberSince 100% · houseLifetimeLotCount 97.3% · lowEstimate 93.0% ·
highEstimate 88.3% · images 99.3% · houseEmail 100% · housePhone 99.0% ·
descriptionIsTruncated 0% (this route does not truncate) · attributes 0% (this route
does not send them — which is why the actor keeps the value from the listing rather than
overwriting it).
Auction-house rows — n = 363 (every house on the board)
| field | fill | field | fill |
|---|---|---|---|
houseName houseUrl houseEmail | 100% | houseRegisterNumber | 99.2% (360/363) |
housePhone | 98.6% | houseVatNumber | 92.0% |
street postalCode city | 100% | houseWebsite | 89.0% |
country | 99.7% (see Honest limits) | houseAgreementNumber | 52.1% |
houseMemberSince | 100% | houseLifetimeLotCount | 97.0% |
upcomingSales | 100% | houseMemberYears | 94.2% |
houseProfile | 53.7% | topResults (hammer prices) | 31.1% |
houseShippingOffer | 25.6% | team (named auctioneers) | 14.6% |
What you can point it at
Leave everything empty and it walks the whole live board. Otherwise, any combination of:
-
Drouot URLs pasted from the browser, in any of the six site languages. A URL the actor cannot walk is named in the log, never silently dropped. What each one means depends on the Row type:
pasted URL in lotsin salesin auctionHouses/en/v/184215-…a saleits whole catalogue that one sale the house running it /en/l/34888742-…a lotthat one lot — — /en/c/626/paintingsa categoryits lots — — /en/s?query=bernard+buffetmatching lots — — /en/auctioneer/840/…a houseevery lot in its upcoming sales its upcoming sales (1 request) that house /en/auctions/futurethe boardevery lot on the board all 809 sales all 364 houses -
Search term — Drouot's own full-text lot search.
-
Categories — all 116 ids from Drouot's own tree (6 macro, 27 categories, 83 sub-categories), with the hierarchy shown in the picker.
-
Sale IDs — the numbers out of
/v/URLs. -
Language —
enfrdeesitzh.
Filters (a filtered row is never delivered and never charged)
Auction-house country (the 27 measured values, each with its share of the board), sale type (LIVE / ONLINE / CATALOGUE / COURANTE), sale status, estimate band, and only rows with an email or a phone.
Depth (costs requests, never extra charges)
- Open each lot page — the untruncated description, the auctioneer's original-language text, every photo, the category ids. One extra request per lot.
- Add the auction house registry block — registration, agrément and VAT numbers plus the house's own website. One request per distinct house, cached: the 809-sale board costs 364 lookups, not 809.
- Add the full terms of sale — one request per sale, 100% fill.
What a run actually costs in requests
drouot.com tolerates about 4 requests a second and no more (see Honest limits), so run time is requests ÷ 4. These are measured, not estimated:
| what you asked for | rows | requests | wall clock |
|---|---|---|---|
| 25 lots off the board (the demo scope) | 25 | 18 | 15 s |
| 1,000 lots off the board (the default) | 1,000 | 28 | 21 s |
| 20 lots from a category URL | 20 | 17 | ~10 s |
| 30 sales + terms + registry | 30 | 75 | ~25 s |
| 8 auction houses | 8 | 25 | ~12 s |
| 10 lots from a search, with lot pages and registry | 10 | 180 | ~60 s |
The last row is the worst case and worth understanding: category and search listings do not carry the auctioneer contact, so each distinct sale behind them has to be opened once (and each lot, and each house, when you turn those on). Ten search hits spread across ten different sales run by ten different houses is the least cache-friendly shape there is. Walking a sale or the board is far cheaper per row, because one request brings 100 lots that already share one contact.
Pricing
$0.0018 per row delivered. No run-start fee. That is $1.80 per 1,000 rows, and it is the only charge: a filtered-out row, a sale that does not exist, a sale with no catalogue and an unreachable URL are all free, and opening lot pages or joining the registry block does not add an event.
Measured for you, so the numbers are comparable: the 1,000-row default scope took 28 requests, 3.76 MB and 20.8 seconds; the 25-row demo scope took 18 requests, 2.70 MB and 15.0 seconds.
Compared with the other Drouot scrapers on the store
There are exactly two, scanned 2026-09-18 across drouot, encheres, auction house,
art auction and auction lots: saswave/drouot-scraper ($0.002/result FREE tier plus an
actor-start fee, 2 users in 30 days, 15 of its 60 public runs FAILED) and
dadhalfdev/drouot-scraper ($0.005/result FREE tier, 0 users in 30 days).
Everything they deliver, this delivers, and it is named here field by field so you can check:
| their field | here | their field | here | |
|---|---|---|---|---|
url / sku / id | lotUrl / lotId | store_name / auctioneer_name | houseName | |
obj_name / title | title | store_address / address | street | |
description | description | store_city / city | city | |
category | categories + categoryPath | store_zipcode | postalCode | |
estimate_low / _high / _range | lowEstimate / highEstimate / estimateRange | phone / auctioneer_phone | housePhone | |
last_bid / current_bid | currentBid | email / auctioneer_email | houseEmail | |
next_bid | nextBid | auctioneer_id | houseId | |
result | hammerPrice | image / image_url | imageUrl | |
auction_status / sale_status | saleStatus | images | images | |
auction_type / sale_type | saleType | lot_number | lotNumber | |
bidding_end | biddingEndsAt | sale_id / sale_url / sale_title | saleId / saleUrl / saleTitle | |
bidding_start | biddingStartsAt | sale_date / timezone | saleDate / saleTimeZone | |
frais_vente / sale_fees_percent | buyerPremiumPercent | currency | currency | |
reserve_price_met | reserveNotReached (the inverse — Drouot's own field is reserveNotReached, so that is what is reported rather than a flipped copy) | lot_count | lotCount | |
record_type | recordType |
One rival field is cut: saswave's availability, which is an empty string in the example row of
their own README and which has no counterpart anywhere in Drouot's payloads. A column of empty
strings is not a field.
What is here that is not there:
- The auction house as a first-class row — 364 of them, with the registration number (99.2%), VAT number (92.0%), agrément number (52.1%), own website (89.0%), named auctioneers and published hammer prices. Neither rival has an auction-house mode at all.
countryresolved from a bare integer. Drouot stores country as75/228with no dictionary anywhere in its data — even its own schema.org output emits"addressCountry": 228. All 27 values on the live board are resolved here; anything unresolved staysnullbeside itscountryIdrather than being guessed.descriptionIsTruncated. The listing routes cut descriptions at exactly 500 characters with no ellipsis and no flag (5.8% of lots). This actor flags every one and offers to re-read them.saleTerms— the full conditions of sale, 100% fill.registrationDeadline— 100% fill; the date after which a bidder cannot register.attributesresolved to labels (colour, dimensions, brand, movement, material) on 24.0% of lots, andcategoriesresolved to names from the 116-id tree.catalogPdfUrlandexternalCatalogUrl(the house's own Interenchères listing).- Filters that reduce your bill — country, sale type, status and estimate band are applied before delivery, so you are not charged for rows you asked not to have.
- A
RUN_SUMMARYthat reconciles what Drouot said was there against what was read, counts this run's own per-field fill, and keeps the three kinds of nothing apart. - No run-start fee (saswave charges one), and the lowest per-row price of the three.
Honest limits
- Hammer prices barely exist on drouot.com, and this is the one place a rival's field is mostly
empty.
hammerPricewas0on all 62,440 lot rows from the forward board. Sampling 500 lot pages spread evenly across all 201,820 URLs in Drouot's own sitemap: 499 answered, 36 belonged to CLOSED sales, and only 4 carried a hammer price — 0.8% of all lots, 11.1% of closed lots. Drouot's full sold-price archive is a separate paid product (gazette-drouot.com). The field is shipped because it is real when it is there, and reported asnull— never0— when it is not. The dense source of realised prices here istopResultson auction-house rows: 31.1% of the 363 houses publish their top lots with the price they fetched. - 19% of upcoming sales have no catalogue to scrape. Of the 809 sales on the board, 154 sale
pages return "sale not found" — the auction is announced but its lot list is not published yet.
In
salesmode you still get all 809 rows with their contacts; inlotsmode those 154 produce nothing, and you are not charged for them. RUN_SUMMARY lists them. - A closed sale withdraws its catalogue. CLOSED sales return an empty lot list. Individual lot pages survive, so the way to keep a closed catalogue is to capture it before the hammer.
- Listing descriptions are cut at 500 characters (5.8% of lots). Turn on Open each lot page for the full text — at one extra request per lot.
- One country id could not be resolved. Id
44(one house in Taipei) has no English rendering anywhere the actor could read, so its rows carrycountry: nullwithcountryId: 44. 362 of 363 house rows and 100% of lot and sale rows resolved. - drouot.com rate-limits at about 4 requests a second. Measured over its own 619-URL sale sitemap: 4.00 req/s gave 615 × HTTP 200 and zero 429s; unthrottled at ~52 req/s gave 493 × HTTP 429. The actor holds itself to 4 req/s and halves that for 30 seconds if a 429 slips through. The practical consequence: the entire ~214,000-lot corpus is about 2,200 requests, i.e. roughly 9 minutes, and there is no way to make it faster without being blocked.
- The board moves while you read it. Walking the 17 pages took the source's own
totalItemsfrom 835 to 836 and returned 809 distinct sales. Sales are deduplicated by id and the shortfall is reported, never silently accepted as "that is all there is". currentBidonly exists where bidding is open — 22.0% of lots in ONLINE sales, 0% in LIVE or CATALOGUE sales, which have not opened yet. That is the source's behaviour, not a gap.houseLifetimeLotCountandhouseMemberSinceare absent from the sale board. Drouot sendslotCount: 0there for every house, including one with 27,204 lifetime lots. They are reported asnullon those rows and filled in properly by Add the auction house registry block or by Open each lot page.attributesare on listing rows and not on lot pages. Opening lot pages therefore keeps the listing's attributes rather than overwriting them with nothing.- Search results depend on the language. "buffet" returned 308 lots on
/enand 452 on/fr— the index is per-language. Set Language to match how the catalogue is written. saleAnnouncement(the press note) is on the sale's own page, not the board: 10.7% of sales publish one.
Source, access and legality
The data is the same JSON payload drouot.com's own pages are rendered from
(…/__data.json, SvelteKit). No login, no API key, no browser automation, and nothing behind a
paywall — the actor reads the public catalogue exactly as a visitor's browser does, at a rate the
site tolerates without complaint.
https://drouot.com/robots.txt, read 2026-09-18, contains both of these, verbatim:
Disallow: /l/*Disallow: /v/*
and, in the same file:
Sitemap: https://drouot.com/sitemap-en-lot.xmlSitemap: https://drouot.com/sitemap-en-sale.xml
— sitemaps that contain nothing but /l/ and /v/ URLs, published for search engines to crawl.
A second stanza of that file gives ClaudeBot, GPTBot, CCBot, anthropic-ai, Scrapy,
Bytespider and 27 other named agents a blanket Disallow: /; this actor is none of them and never
identifies itself as one.
Drouot publishes each house's contact because French law makes it mandatory: Code de commerce
L321-4 et seq. requires every opérateur de ventes volontaires to be declared to the Conseil des
maisons de vente and identified in all sale publicity. That is why houseEmail is at 100% and why
the houseAgreementNumber field exists at all.
Reproducing the numbers in this README
Everything above comes from bytes in fixtures/, captured through the Apify proxy on 2026-09-18 and
listed with URL, status and size in fixtures/CAPTURE_MANIFEST.json. Run
node offline_validate.mjs
with no network and no node_modules to re-check the parser, the pagination guard, the null
handling, the dictionaries and the packaging against those bytes. SIGNOFF.md carries the full
measurement log.