LoopNet Commercial Listings Scraper avatar

LoopNet Commercial Listings Scraper

Pricing

from $0.75 / 1,000 results

Go to Apify Store
LoopNet Commercial Listings Scraper

LoopNet Commercial Listings Scraper

Scrape LoopNet commercial real estate by market: around 25 listings per search with listingId, asking price, the quoted priceText, pricePerSqft lease rates, buildingSqft, propertyType such as Office, Retail or Industrial, yearBuilt, brokerName and the full address. For sale or for lease, no login.

Pricing

from $0.75 / 1,000 results

Rating

0.0

(0)

Developer

String

String

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 days ago

Last modified

Share

What does the LoopNet Commercial Listings Scraper do?

This Actor pulls commercial real estate listings off LoopNet's market search. Give it a market slug such as austin-tx and you get roughly 25 listings back with the asking figure, the building size, LoopNet's property type, the year built, the listing broker and the full address. One request per market, sale or lease.

Commercial is a different animal from residential, and the output reflects it. A single listing often covers several units and is quoted as a span rather than a number: $649,180 - $5,750,515, or $12.00 - $14.00 SF/YR. Any one number picked out of a span would be invented, so those rows keep the span verbatim in priceText and leave price and pricePerSqft as null. Nothing here is made up to fill a column.

  • price for a whole-property sale figure, pricePerSqft for a lease rate, never both on one row
  • propertyType straight from LoopNet's own taxonomy: Office, Retail, Industrial and the rest
  • brokerName on listings where LoopNet names the brokerage
  • Every property type on a market search comes back in one pass; there is no per-type filter to set
  • No LoopNet account, cookie or API key anywhere in the run

What data does it extract?

FieldTypeDescription
listingIdstringLoopNet's own listing ID, stable across runs. Use it to de-duplicate
titlestringThe listing headline, often a building or property name
addressstringStreet address as the listing states it
citystringCity
statestringTwo-letter state code
zipcodestringZIP code
pricenumberWhole-property asking price on a sale, e.g. 2750000. null on a span or a lease
priceTextstringThe figure exactly as LoopNet quotes it, spans and "Contact for price" included
pricePerSqftnumberLease rate, which LoopNet quotes per square foot per year
buildingSqftnumberBuilding size
propertyTypestringLoopNet's own category, e.g. Office, Retail, Industrial
yearBuiltnumberYear of construction, where the listing states it
brokerNamestringListing broker or brokerage, where LoopNet names one
detailUrlstringLink to the LoopNet listing page
searchLocationstringThe market from your input that produced this row
sourceUrlstringThe LoopNet search URL the row was read from
collectedAtstringISO timestamp of the fetch

There are no coordinates. LoopNet's search cards carry city, state and ZIP but no latitude or longitude, so the fields are absent rather than guessed at from the address.

Why scrape LoopNet?

Commercial data is expensive and mostly sits behind subscriptions. LoopNet is the one large source that publishes asking figures on an open page, which makes it the practical starting point for anyone who is not already paying for CoStar.

Asking price next to building size gives you a price-per-square-foot distribution for a market's office or industrial stock without calling a single broker. pricePerSqft does the same job for leases, where LoopNet's per-square-foot-per-year rate compares directly across a submarket once you filter on propertyType.

For acquisition work, filtering on property type and year built across several markets at once builds a target list of older stock in an afternoon. brokerName on live inventory shows who actually controls listings in a market, which beats a directory. And re-running a market on a schedule, keyed on listingId, tells you what entered, left or re-priced since last time.

How to use it

  1. Start from this page: Try for free, or save the Actor to your Apify account.
  2. Put your markets in the Markets field, one per line. LoopNet's own slug form is austin-tx; Austin, TX is normalised to the same thing, so either works.
  3. Pick a Listing type: for-sale or for-lease. Note the hyphens, which is how LoopNet spells them in its own URLs.
  4. Set Maximum results for a hard ceiling, and Concurrency if you are sweeping many markets.
  5. Click Start, then export from the Dataset tab as JSON, CSV or Excel.
  6. The run's SUMMARY record lists any market that failed and the error it produced.

If you are unsure of a market slug, open the market on LoopNet and read it out of the URL: https://www.loopnet.com/search/commercial-real-estate/austin-tx/for-sale/.

Input

FieldTypeDefaultDescription
locationsarray of stringsrequiredLoopNet market slugs, e.g. "austin-tx". "Austin, TX" normalises to the same slug. Between 1 and 100 entries
listingTypestringfor-salefor-sale or for-lease
maxItemsinteger1000Ceiling on dataset rows, 1 to 50000
concurrencyinteger2Markets fetched in parallel, 1 to 5
{
"locations": ["austin-tx", "Dallas, TX", "phoenix-az"],
"listingType": "for-sale",
"maxItems": 1000,
"concurrency": 2
}

Output

One row per listing. The shape below is illustrative — it shows the fields and their types, not a captured run.

{
"listingId": "34018207",
"title": "Brazos Tower",
"address": "701 Brazos St, Austin, TX 78701",
"city": "Austin",
"state": "TX",
"zipcode": "78701",
"price": 2750000,
"priceText": "$2,750,000",
"pricePerSqft": null,
"buildingSqft": 18400,
"propertyType": "Office",
"yearBuilt": 1984,
"brokerName": "CBRE",
"detailUrl": "https://www.loopnet.com/Listing/701-Brazos-St-Austin-TX/34018207/",
"searchLocation": "austin-tx",
"sourceUrl": "https://www.loopnet.com/search/commercial-real-estate/austin-tx/for-sale/",
"collectedAt": "2026-08-21T09:14:03.512Z"
}

A lease row inverts the two price fields: pricePerSqft holds 14 for a listing quoted at $14.00 SF/YR, and price is null.

Reliability

Each listing is read from the search page's own listing cards, with LoopNet's schema.org listing data joined onto it by listing ID. Neither source alone is enough. The cards are the complete result set, since the schema.org block drops portfolio listings, but only the schema.org block names the listing broker. Joining them is what produces the full field set.

Two parsing decisions are worth knowing about, because they change what you get:

Building size is only taken from a chip that opens with a single figure. A lease placard leads with the range of available spaces (986 - 7,202 SF), which is a different quantity from the building size, so those fall through to the schema.org description, which states one figure for the whole property.

The agent's marketing paragraph is excluded from fact extraction. It is prose, and left in it would happily yield a "year" or a "price" that belongs to a sentence rather than to the building.

A market that cannot be read is recorded in the run's SUMMARY under failures rather than quietly returning fewer rows, and a run where every market failed exits with an error. There are no retries: the String Unblocker behind this Actor owns proxy rotation and solver selection, so a retry loop out here would re-roll the same block.

Limitations

One search page per market, so this is a market sampler rather than a full LoopNet crawl. Run more markets to widen coverage. Photos, broker phone numbers and email addresses, lot size, coordinates, tenant details and the space-by-space availability breakdown of a multi-unit listing are all out of scope. Listings without a single quoted figure carry null in price and pricePerSqft by design. US markets only.

How much does it cost?

Pricing is per event: one charge for each result row written to the dataset. A market that fails produces no rows and costs nothing. The current rate is in the pricing panel at the top of this page.

Runs started from an Apify free plan stop at 250 requests and 250 results, reported in the run's status message; any paid plan runs the full input and whatever maxItems you set. The cap is there because this Actor fetches through String's own infrastructure, which Apify does not reimburse on free-plan runs, and it binds on requests as well as rows so a long market list cannot spend those fetches on rows the run will not return.

Using it with the Apify API

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });
const run = await client.actor("usestring/loopnet-listings").call({
locations: ["austin-tx", "phoenix-az"],
listingType: "for-lease",
maxItems: 500
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const officeRates = items
.filter((row) => row.propertyType === "Office" && row.pricePerSqft !== null)
.map((row) => row.pricePerSqft);
console.log(officeRates);
const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord("SUMMARY");
console.log(summary?.value);

The Actor reads LoopNet's public market search, the page any logged-out visitor can open. No account, no session cookie, no paywall. Collecting information from a page published to the open web is lawful in the US and the EU under current case law; what invites trouble is circumventing a login or ignoring an access control, and neither happens here.

Commercial listings are business records rather than personal data. The only party named is the listing brokerage, published by LoopNet as business contact information, and no phone numbers or email addresses are collected. Listing copy and photography belong to whoever produced them, so treat the text as source material for analysis rather than something to republish. This is not legal advice.

FAQ

Do I need a LoopNet account, API key or cookies? No. The Actor reads the public market search as a logged-out visitor and never signs in.

How many listings do I get per market? Around 25, which is one LoopNet search page. Ten markets return roughly 250 rows for ten requests, and coverage widens by adding markets rather than by paging deeper.

Why is price sometimes null? Because the listing quotes a range covering several units, or says "Contact for price". The quoted text is always kept in priceText, so you can see exactly what LoopNet said.

Where do lease rates appear? In pricePerSqft, LoopNet's per-square-foot-per-year rate. A sale listing puts its whole-property figure in price instead, and no row carries both.

Does it return coordinates? No. LoopNet's search cards carry city, state and ZIP but no latitude or longitude, so those fields are not emitted rather than guessed.

Can I filter by property type? Not on input. A market search returns every type and each row is labelled in propertyType, so filter after the run.

Which countries does it support? The United States only. This Actor targets loopnet.com.

Feedback

If a market fails, or a price parses in a way that looks wrong, open an issue from the Issues tab on this Actor's Store page and include the market slug and listing ID.