Retrieve the structured content exposed on a Newmark Merrill commercial property detail page, including the title, address, property facts, leasing contact, tenant logos, downloadable assets, gallery images, and traffic information.
Use Cases
Use for a known Newmark Merrill property detail URL or property slug. The site uses the stable URL pattern https://newmarkmerrill.com/property/{property-slug}/.
Automation Flow
- Build the direct URL as
https://newmarkmerrill.com/property/{property-slug}/and navigate to it. - In the same browser call, run this evaluator on the loaded page:
(() => {
const text = (el) => el?.innerText?.trim() || null;
const field = (label) => {
const heading = [...document.querySelectorAll("h2.heading-5")].find((h) =>
text(h)?.toLowerCase().includes(label.toLowerCase()),
);
const li = heading?.closest("li");
if (!li) return null;
const value = text(li)?.replace(new RegExp(label, "i"), "").trim();
return value || null;
};
const href = (selector) => document.querySelector(selector)?.href || null;
return {
url: location.href,
title: text(document.querySelector("h1.entry-title, h1")),
address:
text(document.querySelector(".entry-header .fa-ul li.lead")) ||
text(
document.querySelector(
".address, .property-address, .center-address, [class*=address]",
),
),
intersection: field("Intersection"),
description: (() => {
const heading = [...document.querySelectorAll("h2.heading-5")].find((h) =>
text(h)?.toLowerCase().includes("description"),
);
return (
text(heading?.closest("li")?.querySelector("ul")) ||
text(heading?.closest("li"))
);
})(),
sqft: field("SQFT"),
population: field("Population"),
dailyTraffic: field("Daily Traffic"),
householdIncome: field("Household Income"),
leasingContact: field("Leasing Contact"),
phone: field("Phone"),
email:
document.querySelector('a[href^="mailto:"]')?.href?.replace(/^mailto:/, "") ||
null,
categories: field("Categories"),
tenants: [...document.querySelectorAll(".tenant-container img")]
.map((img) => (img.alt || "").replace(/ logo/gi, "").trim())
.filter(Boolean),
galleryImages: [...document.querySelectorAll(".jld-slide-slideshow img")]
.map((img) => ({ src: img.src || null, alt: img.alt || null }))
.filter((img) => img.src),
sitePlan: href('a[href*="site-plan"]'),
brochure: href('a[href*="brochure"], a[href*="Brochure"], a[href*="rochure"]'),
customerTraffic: text(document.querySelector(".customer-counter")),
headings: [...document.querySelectorAll("h2, h3")]
.map((h) => ({
level: h.tagName.toLowerCase(),
text: text(h),
className: h.className || null,
}))
.filter((x) => x.text),
};
})();Possible Friction Points
- Property pages are WordPress-style routes under
/property/{property-slug}/; the slug is generally supplied by the caller or URL and should not be guessed from an opaque identifier. - Core property facts are represented as
h2.heading-5headings inside list items. Read the containingli, rather than only the heading or its immediate sibling. - The address is normally the lead item under
.entry-header .fa-ul; generic address-class fallbacks are useful when the theme varies. - Tenant names are encoded in the
altattributes of images under.tenant-container, not necessarily as visible text nodes. - Gallery images use
.jld-slide-slideshow img. Download links may containsite-planorbrochurein their URL, but should be treated as optional because not every property provides both. - Leasing email may appear in a general mailto link or in the leasing/contact section; return the first available
mailto:address. - Some fields and sections are optional. Preserve missing values as
nullor empty arrays rather than inferring them from nearby text.