Estate Sale Scraper with Full Photo Galleries (EstateSales.net) avatar

Estate Sale Scraper with Full Photo Galleries (EstateSales.net)

Pricing

from $5.00 / 1,000 results

Go to Apify Store
Estate Sale Scraper with Full Photo Galleries (EstateSales.net)

Estate Sale Scraper with Full Photo Galleries (EstateSales.net)

Scrape estate, garage, and yard sales from EstateSales.net — with every listing's FULL photo gallery (images[]), not just one thumbnail. Nationwide, per-state, or per-ZIP. Plain-HTTP Cheerio crawling keeps cost ~10x below browser-based scrapers.

Pricing

from $5.00 / 1,000 results

Rating

5.0

(1)

Developer

Scrapelab Max

Scrapelab Max

Maintained by Community

Actor stats

2

Bookmarked

3

Total users

1

Monthly active users

2 days ago

Last modified

Share

Scrape estate, garage, and yard sale listings from EstateSales.net — including each listing's full photo gallery (images[]), not just one thumbnail.

The scraper runs on plain HTTP requests (no headless browser at any point), which keeps its cost profile roughly 10× cheaper than browser-based scrapers (~3,000 pages per compute unit vs. ~300).

Why this scraper?

  • 📸 Full photo galleries — every listing includes its complete gallery as images[] (default up to 25 photos per listing, configurable), in the site's original order. Most alternatives give you a single thumbnail.
  • 💰 Cheap to run — pure HTTP crawling, no browser. Zero-photo listings never trigger an extra page fetch.
  • 🇺🇸 Three coverage modes — specific ZIP codes, a whole state, or every active sale nationwide.
  • Fail-loud integrity — a blocked or partially-broken crawl fails the run visibly instead of silently returning an incomplete dataset.

Coverage modes

Choose exactly one per run:

ModeInputWhat it does
ZIP"zips": ["77098", ...]Scrapes the listings around each ZIP code.
State"state": "TX"Walks every city in the state and scrapes each one.
Nationwide"nationwide": trueEnumerates every currently-active sale in the US via the site's sale sitemap.

Input

FieldTypeDefaultNotes
zipsstring[][]ZIP codes to scrape. Ignored if state or nationwide is set.
statestringTwo-letter state code (e.g. TX). Overrides zips.
nationwidebooleanfalseScrape every active sale in the US. Overrides zips and state.
maxItemsnumber(required)Hard cap on emitted listings — the crawler stops cleanly the moment it's reached, so cost is always bounded.
includeImagesbooleantrueWhen true, listings with photos get one detail-page fetch to collect the full images[] gallery. When false, images is [] (cheapest mode).
maxImagesPerListingnumber25Caps gallery size per listing. Truncation is logged, never silent.
excludeTypesstring[][]Sale types to drop, matched case-insensitively against each listing's type (e.g. OnlineOnlyAuctions). Empty = emit every type.
proxyConfigurationobject{ useApifyProxy: true }Apify proxy settings. Datacenter proxies by default.

Example minimal input:

{ "zips": ["77098"], "maxItems": 25 }

Filtering out sale types (excludeTypes)

To skip online-only auctions, for example:

{ "zips": ["77098"], "maxItems": 25, "excludeTypes": ["OnlineOnlyAuctions"] }

Matching is case-insensitive against the site's verbatim type value. The console offers a multi-select dropdown of the observed types: EstateSales, OnlineOnlyAuctions, MovedOffsiteToStore, MovedOffsiteToWarehouse, and MovingSales (if the site introduces a new type, it needs to be added to the actor's option list before it can be excluded). Every dropped listing is counted in OUTPUT as itemsExcluded.

In ZIP/state mode the type is known from the search page, so excluded listings never consume a maxItems slot — you still get a full maxItems of wanted listings. In nationwide mode the sale type is only known after each detail page is fetched, so excluded listings still count toward maxItems there: a nationwide run with excludeTypes set can report capHit: true while emitting fewer than maxItems items (itemsEmitted + itemsExcluded accounts for the difference).

Output

One dataset item per sale listing:

{
"id": 118342,
"title": "Estate Sale in Houston, TX - Antiques, Furniture & Collectibles",
"type": "Estate Sale",
"company": "Caring Transitions of Houston",
"address": "1234 Bissonnet St",
"city": "Houston",
"state": "TX",
"zip": "77098",
"latitude": 29.7189,
"longitude": -95.42,
"dates": [
{ "start": "2026-07-24T09:00:00-05:00", "end": "2026-07-24T16:00:00-05:00" },
{ "start": "2026-07-25T09:00:00-05:00", "end": "2026-07-25T14:00:00-05:00" }
],
"photo_count": 42,
"main_image": "https://media.estatesales.net/img/listings/118342/main.jpg",
"thumbnail": "https://media.estatesales.net/img/listings/118342/thumb.jpg",
"is_featured": false,
"url": "https://www.estatesales.net/TX/Houston/77098/118342",
"scrapedAt": "2026-07-21T14:32:07.418Z",
"images": [
"https://media.estatesales.net/img/listings/118342/main.jpg",
"https://media.estatesales.net/img/listings/118342/img-02.jpg",
"https://media.estatesales.net/img/listings/118342/img-03.jpg"
]
}

Field guarantees:

  • dates[].start/end are always offset-aware ISO-8601 timestamps (never naive/local).
  • images[0] always equals main_image when both exist; gallery order matches the site.
  • Field names and types are a stable contract — new fields may be added over time, but existing ones are never renamed, removed, or retyped.

Exporting results (JSON, CSV, Excel, XML)

Every run's dataset can be downloaded in JSON, JSONL, CSV, Excel (XLSX), XML, HTML, or RSS from the run's Storage → Export dialog, or via the Dataset items API (?format=csv, ?format=xlsx, ...).

Two ready-made table views are included for clean flat exports:

  • Sales — one row per sale (id, title, type, company, address, city, state, zip, photo count, main image, listing URL). Ideal for spreadsheets.
  • Images (one row per photo) — the images[] gallery unwound so each photo URL is its own row alongside the sale's id, title, and location. Ideal for feeding image pipelines or downloading galleries in bulk.

Select a view in the Export dialog (or pass ?view=sales / ?view=images on the API) to get that shape in any format. Exporting without a view returns the full raw items, including the complete images[] array and dates[] ranges.

Run integrity

The run is designed to never silently return a partial crawl:

  • A search page that parses to zero listings without the site's "no sales" marker fails the run (guards against the site changing its markup under the scraper).
  • A high ratio of blocked responses (403/429/challenge pages) fails the run instead of emitting a quietly incomplete dataset.
  • Any request that exhausts its retries fails the run rather than dropping listings.
  • Every run writes a stats object (pagesCrawled, itemsEmitted, detailFetches, itemsExcluded, blockedResponses, parseFailures, budgetCap, budgetHit, capHit, ...) to the run's OUTPUT key-value store key and logs it as Run stats: {...}.

If maxItems was reached before full coverage, the run still succeeds and reports capHit: true in OUTPUT — intentional truncation is visible, never silent.

Spending limits are honored the same way: if you set a maximum total charge on the run, the scraper computes how many results your budget pays for, stops cleanly at that number, and reports budgetHit: true (with the computed budgetCap) in OUTPUT — the run succeeds with exactly the results you paid for, instead of being aborted mid-crawl by the platform. A budget too small to pay for even one result fails the run immediately with an explanatory message.

Cost

Plain-HTTP crawling does roughly 3,000 pages per compute unit. Each listing costs at most two page fetches (its search-results share + one detail page for the gallery), and zero-photo listings skip the detail fetch entirely. A 25-listing ZIP run typically consumes well under 0.01 CU. Use maxItems to put a hard ceiling on any run's cost.

Etiquette

The scraper uses polite concurrency and rate limits, a browser-like User-Agent, and respects the site's robots.txt disallowed paths.