← back to Commercialrealestate
TK-10709: strip Crexi marketing-header prefix from detail addresses
963bc1dbb05437403c0fa8169409dddcb686602c · 2026-08-25 15:14:54 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M scripts/scrape-crexi-loopnet.js
Diff
commit 963bc1dbb05437403c0fa8169409dddcb686602c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Aug 25 15:14:54 2026 -0700
TK-10709: strip Crexi marketing-header prefix from detail addresses
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
scripts/scrape-crexi-loopnet.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/scripts/scrape-crexi-loopnet.js b/scripts/scrape-crexi-loopnet.js
index 150ef0b..2cd1867 100644
--- a/scripts/scrape-crexi-loopnet.js
+++ b/scripts/scrape-crexi-loopnet.js
@@ -145,7 +145,12 @@ function detailAgent(url) {
const head = d.head || '';
const flat = head.replace(/\n+/g, ' ');
// authoritative address + headline price (both near the top → in head)
- const address = cleanAddr((flat.match(/([0-9][^,\n]{2,60}?,\s*[A-Za-z .]+,\s*CA\s*\d{5})\s+For Sale/) || [])[1]);
+ let address = cleanAddr((flat.match(/([0-9][^,\n]{2,80}?,\s*[A-Za-z .]+,\s*CA\s*\d{5})\s+For Sale/) || [])[1]);
+ if (address) {
+ // Crexi sometimes prepends a "<type> | X% CAP | N Units " marketing header before the repeated
+ // street address — strip it so the stored address is just the street, city, CA, zip.
+ address = address.replace(/^.*?\b\d+\s+Units?\s+(?=\d)/i, '').replace(/^.*\|\s*/, '').replace(/\s{2,}/g, ' ').trim();
+ }
let price = null;
let m = flat.match(/\$([\d,]{5,})\s*\|\s*\d+\s+days?\s+on\s+market/i); // "$6,500,000 | 169 days on market"
if (!m) m = flat.match(/Listed by[^$]{0,80}?\$([\d,]{5,})(?!\s*\/)/i); // "Listed by <firm> $6,500,000"
← f0860c1 TK-10709: robust Crexi agent-attributed scraper
·
back to Commercialrealestate
·
auto-data-snapshot: 2026-08-25T15:12:26 (2 data files) — dat b362871 →