[object Object]

← back to Homesonspec

docs(toll): wave-2 SOLVED — QMI homes are plain-fetch via sitemap /Quick-Move-In/<id> pages (JSON-LD + __NEXT_DATA__), no browser needed

acd6564e75ec4a18345375d409a2cf6928db5c6f · 2026-08-03 07:44:43 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit acd6564e75ec4a18345375d409a2cf6928db5c6f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 07:44:43 2026 -0700

    docs(toll): wave-2 SOLVED — QMI homes are plain-fetch via sitemap /Quick-Move-In/<id> pages (JSON-LD + __NEXT_DATA__), no browser needed
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 collectors/toll-brothers/WAVE2-RECON.md | 39 ++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/collectors/toll-brothers/WAVE2-RECON.md b/collectors/toll-brothers/WAVE2-RECON.md
index f5db3700..bcccf705 100644
--- a/collectors/toll-brothers/WAVE2-RECON.md
+++ b/collectors/toll-brothers/WAVE2-RECON.md
@@ -22,19 +22,32 @@ object carries **`numQDH`** (quick-delivery-home count), `comingSoonQMICount`,
   337KB). It has NO embedded homes JSON, NO `__NEXT_DATA__`, and NO visible
   `/api/` references — homes load via a **runtime XHR** after hydration.
 
-## The remaining crack (the fresh-session task)
-Browser-trace ONE Toll community detail page (Playwright/Browserbase network
-capture) to catch the XHR that loads its QDH homes. Community `3131 Camino`
-(communityId **14614**, California, numQDH **7**) is a good probe target.
-Once the endpoint + params are known, build a Pulte-style JSON adapter:
-1. `fetch()`: get homesearchV5.json → filter communities to numQDH>0 → for each,
-   call the (traced) QMI endpoint.
-2. `extract()`: emit `entityType:"community"` (as today) PLUS `inventory_home`
-   records from the QMI payload. Capture core fields + a `specs` map (Toll should
-   expose was-price/incentives/plan — follow the DR-Horton/Pulte specs pattern,
-   commit `7c3609c`).
-3. Respect robots: `/siteplans /nse /compare /new-homes /sitesearch` are
-   disallowed; `/api/` is allowed. NO bot-wall circumvention (standing rule).
+## SOLVED (2026-08-03 browser-trace) — it's PLAIN-FETCH, no browser needed
+The community amplify pages render homes client-side (dead end — don't chase).
+But the INDIVIDUAL QMI home pages are plain-fetch with clean structured data:
+- **URL pattern (in the sitemap):**
+  `https://www.tollbrothers.com/luxury-homes-for-sale/<State>/<Community>/Quick-Move-In/<id>`
+  e.g. `.../Quick-Move-In/283595`. Also a `.../Quick-Move-In/MLS-<n>` alias for the
+  same home — DEDUPE (prefer the numeric-id URL; drop the MLS- duplicate).
+- Each page (~80KB, HTTP 200, plain curl w/ a real UA) carries BOTH:
+  - **JSON-LD `SingleFamilyResidence`** (the clean parse target): `name` (plan),
+    `floorSize.value`→sqft, `address.{streetAddress,addressLocality,addressRegion,postalCode}`,
+    `geo`→lat/lon, `numberOfBedrooms`, `numberOfFullBathrooms`+`numberOfPartialBathrooms`,
+    `containedIn`→community, `image`, `description`. **NOTE: price is NOT in the JSON-LD.**
+  - **`__NEXT_DATA__`** — carries `price` + `lotNumber` (+ likely status, incentives,
+    was-price for the `specs` map). Pin the exact props path during the build.
+
+### Build plan (Pulte-style adapter, plain-fetch)
+1. `fetch()`: GET Toll's sitemap → collect `/Quick-Move-In/<numeric-id>` URLs, drop
+   `MLS-` alias duplicates → plain-fetch each (LiveFetcher; contentHash dedup makes
+   re-runs cheap + resumable, so the ~11k volume is fine over recurring runs).
+2. `extract()`: parse JSON-LD SingleFamilyResidence for core fields; parse
+   `__NEXT_DATA__` for price + lotNumber; emit an `inventory_home` record + a `specs`
+   map (was-price/incentives/plan — follow DR-Horton/Pulte pattern, commit `7c3609c`).
+   The COMMUNITY comes from `containedIn.name` — wave-1 already publishes communities,
+   so the FK target exists (extract community-first only if a home's community is new).
+3. Respect robots: `/siteplans /nse /compare /new-homes /sitesearch` disallowed;
+   `/luxury-homes-for-sale/` + `/api/` allowed. NO bot-wall circumvention (standing rule).
 
 ## Watch-outs
 - Toll Akamai bot-blocks the Kamatera **datacenter** IP under load (Taylor

← f98e35a7 docs(toll): wave-2 recon — ~298 per-community fetches not 11  ·  back to Homesonspec  ·  feat(toll): wave-2 QMI home ingestion (adapter v2.0.0) — pla 1f01a75d →