Collect commercial listing titles, addresses, and detail URLs from the first page of 24 listings in APi Real Estate's expanded 10,000+ property results view. Pagination is not currently working; report this as a partial first page, not the full catalogue.
Use Cases
- Collect commercial listing titles, addresses, and detail URLs from the first page of 24 listings.
- Expand the commercial landing page into its full listings results view.
- Re-run extraction after lazy-loaded listing cards appear.
Automation Flow
- Navigate to
https://www.apirealestate.com/commercial-listingswith a residential proxy. - Solve the reCAPTCHA if presented, then read the
hrefofa[aria-label="More Listings"]andgotoit (/listing?searchId=…; never invent thesearchId). Clicking the link does not navigate. On the/listingpage, wait fora[href*="/listing-detail/"]with a 45000 ms timeout, then wait another 3000 ms: the results render slowly. - Run this evaluator on the expanded results view:
(async () => {
for (let i = 0; i < 12; i++) {
const before = document.querySelectorAll('a[href*="/listing-detail/"]').length;
window.scrollTo(0, document.body.scrollHeight);
await new Promise(r => setTimeout(r, 1000));
const after = document.querySelectorAll('a[href*="/listing-detail/"]').length;
if (after === before) break;
}
const seen = new Set();
const listings = [...document.querySelectorAll('a[href*="/listing-detail/"]')].map(a => {
const url = new URL(a.getAttribute('href'), location.href);
const key = url.origin + url.pathname;
if (seen.has(key)) return null;
seen.add(key);
const article = a.closest('article');
const heading = article?.querySelector('h3, h2, [role="heading"]');
const title = (heading?.innerText || a.innerText || '').trim().replace(/\s+/g, ' ');
const address = (a.innerText || article?.querySelector('h3, h2, [role="heading"]')?.innerText || '').trim().replace(/\s+/g, ' ');
return { title, address, detailUrl: key };
}).filter(x => x && x.detailUrl);
const paginationLinks = [...document.querySelectorAll('a[rel="next"], a[rel="prev"], a[aria-label*="next" i], a[aria-label*="previous" i], .pagination a, [data-page-next] a, [data-page-next]')]
.map(a => { try { return new URL(a.getAttribute('href'), location.href).href; } catch { return null; } })
.filter(u => u && new URL(u).origin === location.origin && !u.includes('/listing-detail/'))
.filter((u, i, all) => all.indexOf(u) === i);
return { listings, paginationLinks };
})();- Follow each returned genuine pagination URL and repeat the evaluator until no new result-page URL remains; if
paginationLinksis empty, do not invent page parameters.
Params
| Param | What it does | Example value |
|---|---|---|
| commercial listings URL | Landing page containing the full-results expansion link | https://www.apirealestate.com/commercial-listings |
| expansion selector | Opens the 10,000+ property results view | a[aria-label="More Listings"] |
| lazy-load wait | Delay between result-list scrolls | 1000 ms |
Possible Friction Points
- Non-www host returns a network error → use
https://www.apirealestate.com/commercial-listingswith a residential proxy. - reCAPTCHA appears → solve it before clicking More Listings.
- Commercial landing page shows 3 featured cards with
/listing-detail/links → they satisfy the wait selector, so confirm the URL path is/listingbefore extracting; otherwise only the featured cards come back. - Navigation links are mistaken for pagination → accept only explicit next/previous/pagination controls and do not guess page URLs when none are present.
- The results pager is
li.page-numitems with nohref(24 listings per page, ~417 pages). Clicking them did not advance the page under automation, sopaginationLinksis empty and the recipe returns the first 24 listings only → report the result as a partial first page, not the full catalogue. - Listing cards carry only an address →
titlerepeatsaddress; detail links carry a ~1,000-character tracking query string, sodetailUrlis returned as origin + path. - Listing cards are lazy-loaded → use the included bounded scroll loop before extraction.
Example Result
{
"listings": [
{
"title": "Example Title",
"address": "Example Address",
"detailUrl": "https://example.com/listing-detail/example"
}
],
"paginationLinks": [
"https://example.com/page/2"
]
}