TrueLocal AU Directory Listings & Reviews Scraper avatar

TrueLocal AU Directory Listings & Reviews Scraper

Pricing

from $1.20 / 1,000 results

Go to Apify Store
TrueLocal AU Directory Listings & Reviews Scraper

TrueLocal AU Directory Listings & Reviews Scraper

Scrape TrueLocal.com.au business listings by keyword, location, or URL. Extract names, addresses, GPS coordinates, phones, emails, websites, ratings, and review counts. Optional review mode exports individual reviews with author, rating, text, and date. Automatic pagination included.

Pricing

from $1.20 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

13

Total users

2

Monthly active users

19 days ago

Last modified

Share

Pull structured directory data from TrueLocal.com.au, the Australian local listings portal. Search by keyword and location (or paste any TrueLocal URL) and get clean records: name, full address, GPS coordinates, phone, email, website, category, star rating, and review count. Flip on the dedicated reviews mode to export every customer review as its own row, with author, star rating, review text, and date. Pagination is automatic, so one search keyword in one location can walk thousands of listings.

Why this scraper

  • Three modes in one actor: keyword + location search, URL paste (search or profile URLs), and a flat one-row-per-review mode.
  • 20+ fields per listing including the listing description, GPS latitude/longitude, public phone (plus secondary), public email, website, full category trail with codes, and structured weekly + holiday opening hours.
  • Reviews are extracted from the profile page the actor already opened, so switching them on costs no extra page fetch and no extra wait. They bill on that same Profile-page enrichment event, in blocks of 10 - and most listings carry no reviews at all, so in practice they add very little.
  • Forward auto-pagination verified to walk fully disjoint result pages (no duplicate rows across pages).
  • Cross-product search expansion: pass several keywords and several locations and every combination is searched.
  • Lean mode (profile fetch off) returns the SERP card alone for fast, low-cost enumeration.
  • Daily/recurring change monitoring: turn on Incremental mode to get only NEW, UPDATED, and REAPPEARED listings on every scheduled run, or resume one specific interrupted crawl with resumeFromRunId.

Data you get

Listing record (search and URL modes), example values are real results captured from the live site:

FieldExample
id00000001
urlhttps://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001
nameSample Listing Name
descriptionThe listing's own description text appears here, when the owner wrote one.
primaryCategorySample Category
categories["Sample Category"]
categoryCodes["00000000"]
phone(02) 0000 0000
secondaryPhonenull
emailcontact@example.com
websitehttps://example.com
fullAddress1 Sample Street, Sydney NSW 2000
suburbSydney
stateNSW
postcode2000
latitude-33.0000
longitude151.0000
openingHours{ "MONDAY": "0000-2359", "TUESDAY": "0000-2359", ... }
holidayHours{ "New Year's Day": [["2026/01/01", "Open 24 Hours"]], ... }
permanentlyClosedfalse
ratingValue5
reviewCount6
reviewsReturned6
reviews[{ "author": "Jane D.", "rating": 5, "body": "...", "date": "2024-01-01" }]
scrapedAt2026-01-01T00:00:00.000Z
changeTypeNEW (incremental mode only, see "Resume & recurring updates" below)
changedFields["phone"] (incremental mode, UPDATED rows only)
firstSeenAt2026-01-01T00:00:00.000Z (incremental mode only)
lastSeenAt2026-01-02T00:00:00.000Z (incremental mode only)

Sample shape, values are illustrative placeholders rather than from a live listing.

Note on description: TrueLocal exposes the listing's own description text when the owner wrote one; listings that never added a description return null (the site shows only an auto-generated title there). openingHours times use a 24-hour HHMM-HHMM format ("0000-2359" = open 24 hours).

Review record (reviews mode), one row per review:

FieldExample
businessId00000001
businessNameSample Listing Name
businessUrlhttps://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001
businessCategorySample Category
businessSuburbSydney
businessStateNSW
businessRating5
businessReviewCount6
authorJane D.
rating5
reviewBodyReview text appears here when reviews are present on the listing.
datePublished2024-01-01

How to use

Search by keyword and location (one record per listing, reviews nested):

{
"mode": "search",
"searchTerms": ["restaurants"],
"locations": ["Sydney NSW"],
"fetchDetails": true,
"fetchReviews": true,
"maxReviews": 20,
"maxPages": 3,
"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AU" }
}

Several keywords across several locations (every combination is searched):

{
"mode": "search",
"searchTerms": ["plumber", "electrician"],
"locations": ["Sydney NSW", "Melbourne VIC"],
"maxPages": 5,
"maxListings": 200
}

URL mode, paste a search URL and a profile URL together:

{
"mode": "url",
"urls": [
"https://www.truelocal.com.au/search?search_terms=cafe&geo_location_terms=Melbourne+VIC",
"https://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001"
],
"maxPages": 2
}

Reviews mode, one row per review (works with search inputs or pasted profile URLs):

{
"mode": "reviews",
"urls": ["https://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001"],
"maxReviews": 50
}

Input parameters

ParameterTypeDefaultDescription
modestringsearchsearch, url, or reviews.
searchTermsarray["restaurants"]Keywords to search (search and reviews modes).
locationsarray["Sydney NSW"]Free-text locations; suburb level is accepted. Every keyword is searched in every location.
urlsarray(none)TrueLocal search and/or profile URLs. In search/reviews modes, pasting URLs here overrides searchTerms + locations.
fetchDetailsbooleanfalseOff by default: runs return the lean SERP card (name, profile URL, phone, category), fast and cheap. Turn on to open each profile page for address, GPS, email, website, rating and reviews; each listing opened bills one Profile-page enrichment event. Reviews mode and pasted profile URLs always fetch profiles.
fetchReviewsbooleanfalseNest a reviews array on each listing record (search/URL modes). Off by default. Requires fetchDetails. Billed on the Profile-page enrichment event in blocks of 10 (1-10 reviews = 1 unit, 11-20 = 2). Cap with maxReviews. Ignored in Reviews mode, which returns review rows as ordinary results.
maxReviewsinteger20Max reviews captured per listing, which also caps what they bill. 0 = all available reviews.
maxPagesinteger(empty = unlimited)Max SERP pages per keyword/location or per pasted search URL. ~30 listings per page. Leave empty (or 0) to walk every result page — the walk stops naturally once a page comes back empty or repeats listings already collected, or sooner once Max listings is reached.
maxListingsinteger20Stop after this many listings across all searches. Defaults to 20 so a run stays small unless you raise it. 0 = unlimited (bounded only by the natural stop on Max pages).
resumeFromRunIdstring(empty)A previous run ID or dataset ID to continue a full-catalogue walk across separate runs. Listings already collected there (matched by id) are skipped, so this run only saves the new ones. For recurring daily/weekly monitoring of the same search, use incrementalMode instead, see "Resume & recurring updates" below.
incrementalModebooleanfalseDaily/recurring monitoring of this same search. First run returns everything as NEW; later runs return only NEW/UPDATED/REAPPEARED by default. See "Resume & recurring updates" below.
stateKeystring(empty)Optional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from your mode/keyword/location/URL and detail settings when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return listings unchanged since the last run, marked UNCHANGED. Adds and bills extra rows you already have.
emitExpiredbooleanfalseIncremental mode only, Search/URL modes only. Also return listings from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search (not capped, not a resume, not Reviews mode). Adds and bills extra synthetic rows.
proxyobjectApify residential AUProxy configuration. AU residential is recommended.

Resume & recurring updates

There are two different things here, pick the one that matches what you're doing:

NeedUse
A crawl stopped and should continueresumeFromRunId / automatic checkpoint recovery
Run the same search every day and receive only changesincrementalMode
Keep separate daily campaigns for similar searchesdistinct stateKey values
Run a normal full snapshotleave both off

Resume (resumeFromRunId) continues one specific interrupted or previous large crawl: paste a run ID or dataset ID and this run skips listings already collected there, returning only the remaining new ones. A checkpoint is also saved automatically as the run progresses: if the run is interrupted by an Apify platform migration or you click Resurrect on a failed run, it picks back up from where it left off in the same run, without re-saving (or re-charging for) businesses it already collected. No input is needed for the checkpoint; it's automatic.

Incremental mode (incrementalMode) is for a schedule (for example, daily): the actor remembers the previous run of the same search by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED listings by default, duplicates and unchanged listings are suppressed (and not charged). Turn on emitUnchanged or emitExpired only when you also want those rows returned (and billed for). State is isolated per mode/keyword/location/URL and detail-mode setup automatically; set stateKey to name or deliberately share a monitoring campaign. In Reviews mode, the same NEW/UPDATED/REAPPEARED suppression applies at the listing level (a listing's reviews are only returned when that listing changed), but emitExpired is not produced, there is no listing-shaped row in a flat per-review dataset to represent a vanished listing.

Scheduled-run example, same search, run daily:

Day 1 (first run ever for this search):

{ "mode": "search", "searchTerms": ["plumber"], "locations": ["Sydney NSW"], "incrementalMode": true }

→ every listing comes back with "changeType": "NEW".

Day 2 (the schedule fires again, identical input):

{ "mode": "search", "searchTerms": ["plumber"], "locations": ["Sydney NSW"], "incrementalMode": true }

→ listings whose phone/address/hours/etc. changed come back as "changeType": "UPDATED" with changedFields listing what changed, brand-new listings come back as "changeType": "NEW", listings that vanished and came back come back as "changeType": "REAPPEARED", and listings that are still there unchanged are not returned at all (suppressed, not charged) unless emitUnchanged is on. Turn on emitExpired to also see listings that disappeared since the last run, marked EXPIRED, once a run completes a full scan (not capped by Max listings/Max pages, not a resume).

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape — the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each record — not the full JSON. Each item becomes one entry with a title (the listing's name / address) and its key fields flattened to plain text (price, beds/baths, agent, URL, …). Nested objects are collapsed to their main value (e.g. an address object → its full-address text) and long lists are trimmed to the first few names. The complete, full-fidelity record always stays in the Apify dataset — the connector copy is a readable digest for browsing in your app.

  • Notion → one page per item (title + a summary body), created under the page you set in notionParentPageUrl.
  • Linear / Airtable / other → one record/issue per item with the same title + fields.

How to enable:

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip — the export only runs when a connector is selected.

Output example

{
"id": "00000001",
"url": "https://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001",
"name": "Sample Listing Name",
"description": "The listing's own description text appears here when the owner wrote one.",
"primaryCategory": "Sample Category",
"categories": ["Sample Category"],
"categoryCodes": ["00000000"],
"categoryId": "00000000",
"phone": "(02) 0000 0000",
"secondaryPhone": null,
"email": "contact@example.com",
"website": "https://example.com",
"fullAddress": "1 Sample Street, Sydney NSW 2000",
"suburb": "Sydney",
"state": "NSW",
"postcode": "2000",
"latitude": -33.0000,
"longitude": 151.0000,
"openingHours": {
"MONDAY": "0000-2359", "TUESDAY": "0000-2359", "WEDNESDAY": "0000-2359",
"THURSDAY": "0000-2359", "FRIDAY": "0000-2359", "SATURDAY": "0000-2359", "SUNDAY": "0000-2359"
},
"holidayHours": { "New Year's Day": [["2026/01/01", "Open 24 Hours"]] },
"permanentlyClosed": false,
"ratingValue": 5,
"reviewCount": 6,
"reviewsReturned": 6,
"reviews": [
{ "author": "Jane D.", "rating": 5, "body": "Review text appears here when reviews are present on the listing.", "date": "2024-01-01" }
],
"scrapedAt": "2026-01-01T00:00:00.000Z"
}

What you are charged for

The Store page shows the current rates. Events are counted like this:

  • Actor start, once per run.
  • Result (apify-default-dataset-item), one per row returned. In Reviews mode each review IS a row, so reviews are billed here and not as Review enrichment.
  • Profile-page enrichment, off by default (Fetch profile pages). One unit per profile page opened for a row you actually received, plus one unit per 10 reviews returned on that row (1-10 reviews = 1 unit, 11-20 = 2, none = 0). So a listing with 15 reviews costs 3 units: 1 for the page, 2 for the reviews. A listing suppressed as UNCHANGED by Incremental mode is neither returned nor billed, even though its page may have been read to detect the change.
  • Reviews have no event of their own - they are billed as extra units of Profile-page enrichment, as described above.

Plan requirement

TrueLocal accepts clean Australian residential IPs reliably. Datacenter IPs (the default on the Apify free plan) are accepted only intermittently; the scraper rotates exit IPs to recover, but results are slower and less complete.

  • Recommended: an Apify plan with the RESIDENTIAL proxy group, country set to AU (Starter and above).
  • Free plan: residential proxy is not included. The scraper falls back to the default Apify proxy and rotates IPs, but some pages may be rejected. You can also paste your own AU residential proxy URLs in the proxy field.
  • Set the proxy country to AU for the most consistent acceptance.