← back to Sublease Agentabrams
crawl/firms/cbre.js
23 lines
'use strict';
// CBRE — public property search at cbre.com/properties. Medium ToS risk: robots-aware,
// public pages only, rate-limited. CBRE's search is a JS app backed by a JSON API; this
// agent probes the public search API and filters to sublease space in the LA market.
module.exports = {
meta: { firm: 'CBRE' },
async crawl({ base, sponsor, upsert }) {
const start = sponsor.listings_url || 'https://www.cbre.com/properties/properties-for-lease';
if (!(await base.robotsAllowed(start))) {
return { cost: 0, notes: 'robots.txt disallows the property search path — not crawled (compliant skip).' };
}
const r = await base.httpGet(start, { timeout: 20000 });
if (!r.ok) return { cost: 0, notes: `search page ${r.status}` };
// CBRE injects an API base + auth into the page; capture the search endpoint hint.
const api = (r.text.match(/https?:\/\/[^"'\s]*(?:search|properties)[^"'\s]*api[^"'\s]*/i) || [])[0]
|| (r.text.match(/"apiBaseUrl":"([^"]+)"/) || [])[1];
if (!api) {
return { cost: 0, notes: 'Public HTML loaded but the property-search API is JS-injected — needs a headless session or an official CBRE feed to enumerate listings. Agent scaffolded.' };
}
return { cost: 0, notes: `Search API hint: ${api}. Next step: authenticate the public search call + filter transactionType=sublease, market=Los Angeles.` };
},
};